Does Redux Saga select return a mutable or immutable state?
See https://github.com/redux-saga/redux-saga
The select operator just uses the Redux store's getState() method internally. So, the return value from the selector function is probably going to correspond to the contents of the store state tree.
Redux itself does not actually stop you from mutating your state. It wants you to handle state immutably, but the base library does not enforce that in any way.
As a result, if your store state tree is composed of plain JS objects, then yes, the return value from select is almost definitely going to be mutable. If your store state tree use made up of something like Immutable.js Maps and Lists, then the return value from select will probably be immutable.
Related
Im using React. and trying to assign an new key value. pair into the object. So first it goes through an if check and if it meets the requirement, I want to add the key value 'author'
if (field.component === 'Author') {
this.props.writer.config.payload.name = 'Jefferson';
console.log(this.props)
}
There are some online articles that tell me to do this way and others that tell me to do Object.assign. Basically though, I just want to add the 'name':'Jefferson' into the object.
See this answer https://stackoverflow.com/a/24943743/1964636
Mutating props in a child component is an anti pattern,
You may want to pass a function as props that can lift state in the child component.
Once you modify the state of it's parent component (assuming the props are part of the parent component's state), it will rerender with updated props.
I've been reading React's Quick Start documentation;
Whether you declare a component as a function or a class, it must never modify its own props
This is a "pure" function, because it doesn't attempt to change its inputs, and always returns the same result for the same inputs:
function sum(a, b) {
return a + b;
}
This in an "impure" function, because it changes its own input:
https://codesandbox.io/s/9z38xv4x7r
function SayHi(props) {
props.name = "Jim"; // TypeError Cannot assign to read only property 'name' of object '#<Object>'
return <h1>Hi {props.name}!</h1>;
}
Why are React props read-only?
A component should manage its own state, but it should not manage its own props. props is essentially "state that is managed by the component owner." That's why props are immutable.
React docs also recommends to treat state as if it's immutable.
That is because by manipulating this.state directly you are circumventing React’s state management, which can be potentially dangerous as calling setState() afterwards may replace the mutation you made.
You may think of React component as a function of its props and state. As you advance through the docs, you'll find that this is the case, as most functions in the React component life cycle have signatures of the form (prop, state) => { //code }.
React docs define props as any arbitrary input given to a component, and the component will render something based on the props ( and sometimes based on state too, if it is a stateful component ). So props is like something that is given to the component for say, reference. Imagine it this way: you are a component, and your parent component gives you a reference book, containing some rules on how you must behave ( a.k.a. render ). Two cases may arise:
You are dumb (stateless): You just read the book, and behave so.
You are smart (stateful): You read the book, and then note some things in your notepad, that you may view, update or delete. You may even take copy down content from the book to your notepad, and then edit the notepad.
Either way, you may not update the reference book given to you. Only the parent component can update it ( example, give you another book, or change its content ).
I don't know if this is a correct representation, but React components work in a similar way. You'll get the hang of it soon. Make sure you read Thinking in React too. Happy coding!
The props of a react component is aimed to store values and functions from its parent component. It's just the pattern, props are immutable. If you want to have a variable that would be mutable, then store it in the state of the component. States are mutable.
From my experimentation, if you have an object as react state (let [state, setState] = useState({})), and you do something like
setState(s => {
s.a = 42;
return s;
})
It will not re-render components that depend on s.a.
If on the other hand you do
setState(s => {...s, a: 42});
It will re-render all components that depend on any field of s.
So it seems to me like it really only looks at whether the returned object reference of the closure is the same as the state it already has or not and makes a binary choice whether to re-render everything or nothing.
Is that correct?
Is there any way to update state in a way that makes it only re-render things that depend on e.g. s.a?
CONTEXT, if it helps: I need this for my application because performance is becoming impractical. My application retrieves JSON information from and API endpoint, which contains a list of 'fields' that describe input fields that the user can use to input data. When the user is done, the application submits this data in a single json. So all input components are controlled, through a single functional state that holds one property per field (I need to be able to programmatically update some fields sometimes). Performance is prohibitive because all fields (quite many now) are updated/re-rendered every time the user types a character in one of them. I sadly cannot create a new state for each field because the amount of fields is not known in advance.
As a note before I begin, this is not okay, and does not work in general. Treat all React state/props as immutable, otherwise you'll have issues.
setState(s => {
s.a = 42;
return s;
})
There is no way to selectively re-render your component, the reason why that mutation on setState doesn't re-render children that depend on s.a is because your component doesn't re-render at all when you update like this because the reference of s doesn't change, so react doesn't see that there's a change.
The only way to make children not re-render when parents re-render is to use React.memo, PureComponent, or shouldComponentUpdate. And those have to be applied to the children rather than the parent.
When does React re-render child component?
Expected to achieve:
Most correct way to modify specific record stored in the Vuex state with one big (batch) write
Context:
Vuex state contains list of records with default values for each record.
Logic
Component initialises and uses getter to get one of the records.
It's needed to add new properties to the record and overwrite existing values.
Question
Is it acceptable to modify the object returned by the Vuex getter and later commit the whole result into the state? And if yes, what would be the best approach considering it will have to overwrite existing record in Vuex.
P.S: I also wonder if it can result in breaking behaviour of other components that are "getting" the same record that will be overwritten, and will appreciate a lot your thoughts on this topic :-)
Don't modify Vuex data except via Vuex mutation
1) First, clone the getter record. Make sure you deep clone if your record has anything but primitive properties, i.e it has properties that are objects or functions. Here are some cloning options, notice that many don't correctly deep clone.
2) Once you're done mutating the clone, call a Vuex action and have that action call a mutation. It's good practice to only call mutations from actions.
3) In that mutation, use Vue.set (or splice) to replace the state record.
4) Yes, if you mutated the getter directly, it would be mutated anywhere else it was used.
See Change detection caveats in the VueJS reactivity guide.
Sometimes you may want to assign a number of properties to an existing object, for example using Object.assign() or _.extend(). However, new properties added to the object will not trigger changes. In such cases, create a fresh object with properties from both the original object and the mixin object:
// instead of `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
I've seen the use of setIn() and set() in some react-redux code:
state.setIn(...);
state.set(...);
I've found some documentation here https://facebook.github.io/immutable-js/
But unfortunately the method is not documented in detail.
I also found some other questions: Using React's immutable helper with Immutable.js
But these do not answer my question.
I understand, that it must do some immutable stuff?
But what's the immutable thing here?
And what's the difference between set() and setIn()?
Why do we need immutable?
Immutable set method only sets immediate properties, I.e. direct children of the object. A setIn let's you set the value of any deep node down the data. set only takes property name. setIn takes an array of keys/index to reach down to the deeply nested element.
var basket = Immutable.Map({"milk":"yes", "flour":"no"});
basket = basket.set("flour", "yes");
basket = Immutable.Map({"fruits":{"oranges":"no"}, "flour":"no"});
basket = basket.setIn(["fruits", "oranges"], "yes");
The getIn/setIn methods are extremely useful when updating states in stores as you can use generic actions and supply the key paths to child components. They can invoke the actions passing the paths as parameters.
set and setIn are one of the immutablejs method which you use to set data in a list or map object. simple example to understand this is lets say you have a this
//note that fromJS is another method which comes from immutablejs library
const iniState = fromJS({
name:null,
friends:fromJS({
name:null
}),
})
in this case you need to update the initial state with the latest then that's where you can use set and setIn methods.
iniState.set('name',"sibusiso Massango").setIn(['friends','name'],"Zweli Mathebula");
this is how you can use the set and setIn method, to find more about this you can read this docs https://facebook.github.io/immutable-js/docs/