Does React Flux library Alt use React's state? - javascript

After completing the guide on the Alt site I am confused if Alt uses Reacts state to set properties? In part 3 - using Stores, it says
Instance variables defined anywhere in the store will become the
state.
It then puts a variable in the store:
this.locations = [];
Yet if I go into the main React component and log the state, after locations is given data of course, I get undefined except on the props?
loggState() {
console.log(this.state); // undefined
console.log(this.locations); // undefined
console.log(this.props.locations); // [object][object]..
}
Can anyone explain the relationship between states and props when using Alt?

In Alt—and indeed most Flux implementations—the store is a totally different part of your application to your components.
A component subscribes to changes in a store, then uses the changed data to update its local state, causing it to re-render.
We derive the initial state of components that use the LocationStore from whatever the store's state is when we instantiate the component.
getInitialState() {
return LocationStore.getState();
},
Then we set up a subscription, listening for changes to the store.
componentDidMount() {
LocationStore.listen(this.onChange);
},
And finally, we use the subscription handler to apply these changes to the component's local state. The way you decide to apply each update is totally up to you.
onChange(state) {
this.setState(state);
},
Each time we call this.setState with a new state, the component will re-render.
You could also use a higher-order component to subscribe to the store, then covert the store's state to props and pass them down to a wrapped component, instead. In which case, your component wouldn't need to be stateful at all.

Related

What is the diff b/w this.name and this.state.name in react?

React has instance property and state property in react in constructor.
Instance property - Its not re-render the view. use to store the value.
State property - Its store and re-render the view.
Apart from above any other reason or difference or when should be use for both instance and state in constructor of React class component?.
Example:
class example extends Component{
constructor(){
this.state = {
name: 'albert'
};
this.name = 'albert';
}
}
When component state changes, it triggers component re-rendering (if it's not set to be ignored in shouldComponentUpdate()).
Changing instance property does not trigger re-rendering.
simple difference for both that is view part rendering.
EX: When State is update the view also update. Sometimes view is need not to reload that time we can store the value in component instance as you mentioned this.name.
Just check with below link to more about state and instance
https://medium.freecodecamp.org/where-do-i-belong-a-guide-to-saving-react-component-data-in-state-store-static-and-this-c49b335e2a00
It depends upon your requirement, which kind of data you are storing within it.
When any state variable is updated, react calls render to make changes in DOM element, so if you want to make any changes in DOM you should use state otherwise instance.
The current best practice is to use local state to handle the state of
your user interface (UI) state rather than data.
from this article
and instance properties when you just want to save some data to use in UI handling, calculations etc.
check this ref react-components-elements-and-instances for futher details
Whenever state is updated, react calls the render() method to update the DOM with required changes, and it should always be updated using setState(). The instance variable will be useful for block level manipulations which would then update the state if required. So if you want to re-render the DOM use state variables, else use instance variables.

If state is immutable, is the whole state replaced on any change?

If state is immutable wouldn't the whole state need to be replaced on any change? Otherwise, you're mutating the state. Are top-level keys held as separate immutable objects?
By definition wouldn't any change need to replace the whole thing? How is this handled by Redux? Wouldn't replacing the full state break PureComponents?
Thanks for any clarification.
Let's break it down step by step:
There is an initial redux store of { color: 'red' }
The user clicks a button
An action is generated, say CHANGE_COLOR
Redux calls your reducer with the store (from step 1) and the action. The reducer returns a new store, say { color: 'blue' }
Then, let's say you had a class Square extends PureComponent with mapStateToProps as (store) => { color: store.color }
What happens now is that when the store changes, redux-react runs the mapStateToProps every time. It then generates new props. These props get sent to react.
If you're with me so far the TL;DR of how redux and react work together is that whenever the redux store changes, every single mapStateToProps runs and this generates new props for your react components.
From this point on, it's standard React. When the props of a React component change, it runs componentWillReceiveProps followed by shouldComponentUpdate.
For a PureComponent, basically that means shouldComponentUpdate just does a shallow equality check on your new props, and goes from there.
Okay, with this base understanding out of the way, nested objects behave similarly.
Instead of a store of {color: 'red'} what if we had a store like this:
{
allMyData: {
color: 'red'
key1: 'someData',
key2: 'lotsMoreData',
bigData: {
nestedKey: 'EvenMoreNestedData',
}
}
Then, your reducer might look something like this:
const reducer = (store, action) => {
if (action == CHANGE_COLOR) {
let newStore = Object.assign({}, store);
newStore.allMyData = Object.assign({}, newStore.allMyData, { color: 'blue' });
}
}
Note that there are better tools to do deep immutable merges. One main point I want to show here is that although the newStore is a different object, both store and newStore BOTH point to the SAME bigData key and the other values that are unchanged. The immutability part allows for this kind of thing to work.
After this, the steps are basically the same. After every store change, mapStateToProps runs and generates a new props object. Redux-react then passes that new prop object to React and in this case, a PureComponent wouldn't render if the prop values have the same identity (===)
Note that redux-react has some perf optimizations where it will avoid calling into react with new props but for the purposes of this discussion I'm omitting that step.
Hope this helps clear up your questions.
TL;DR: Every redux action returns a new store. Every time a new store is generated, mapStateToProps generates new props for every connected react component. If the react component is a pureComponent, it won't re-render because the props haven't changed.
The crux for your question is that because your store is immutable, you can re-use the same inner objects across different stores, and even pass those into your react components via mapStateToProps.
Redux never says that the state is immutable. It says the reducers which constitute the store or state of the application should be immutable and should be pure functions.
Yes the top level keys are seperately considered to be immutable.
So on any change or in Redux terms any action is done we trigger a reducer on each action which causes the state change.

React State management

I am very new to React. On going through the React tutorial, I understand the need to lift the state to the parent component which ensures that the children components can stay in sync and can feed off the major chunk of data residing in the state of the parent. But then , with changing data, won't the setState in the parent fire off the re-rendering of all the children components, decreasing UI performance ? Without using flux or redux, which is the best way to position the state in a react application ?
When you change a component's state, it triggers a re-render for that component.
The re-render will create a new set of virtual elements (returned from the render function), which React uses to represent the new state of the DOM. However, unless there are differences between the virtual DOM and the real DOM, nothing will be changed.
The fact that React's virtual elements are simply lightweight object representations of actual HTML elements makes it fast enough that in most cases, you don't even need to think about the performance cost of calling render for child components.
If, however, you do find yourself with a child component that has a particularly expensive render function—you can prevent it from always re-rendering by implementing shouldComponentUpdate. This allows you to specify with fine grained control, which changes in props or state will actually trigger a component to update.
The other approach is to build a custom state management solution which explicitly ties your components together.
let state = { count: 0 };
let listenForState = null;
function ComponentA() {
let onClick = () => {
state.count += 1;
if (listenForState) listenForState(state);
};
return <button onClick={onClick}>+</button>;
}
class ComponentB extends React.Component {
constructor() {
super();
this.state = state;
}
componentWillMount() {
listenForState(state => this.setState(state));
}
render() {
return <span>{this.state.count}</span>;
}
}
However this quite quickly gets out of hand, and there aren't many situations where it would be better than just lifting state up to a shared parent.
If you find that your state driven child components are nested too deeply in the stateful parent, then it's time to look at Redux instead.
Yes, your mostly right. But you dont need to pass the state of the component to the children, you r passing only props, its not actually the same, because changing of props doesnt need to rerender your component.
There is amazing method in the component lifecycle, called shouldComponentUpdate, default its return true if only shallow equality of states objects are false (if refs are different - thats why mutate of state will not rerender component). And you can also implement this method by yourself, comparing your props to check if you need an update or not. There is a scheme how would it work.
And also, react will not rerender element if the virtual DOM was not changed. So this way you can rerender component if only his props is changed, but if you need to change props of its children - you must rerender current.
Basicly, because of these there is an advice to pull the state of application from top to the leafs component (which returns most of html). You can read about optimization more here.
And must to say :
Your code must become a spaghetti
If you will have a lot of components, which have a lot of events, based on state, so if you need some complex architecture, use Redux or some other global state manager.
If you are looking only for a State Management library, check Duix (https://www.npmjs.com/package/duix).
Redux solves a lot of problems (adding complexity). If you only want to improve the State Management, just take a look at Duix.
PS.: I created that library

One-Way Data Flow: Child component doesn't update when prop is asynchronously updated by parent

All props form a one-way-down binding between the child property and
the parent one: when the parent property updates, it will flow down to
the child, but not the other way around. This prevents child
components from accidentally mutating the parent’s state, which can
make your app’s data flow harder to reason about. In addition, every
time the parent component is updated, all props in the child component
will be refreshed with the latest value. - One-Way Data Flow
The Vue2 Component Docs suggests doing the following to use props as an initial value:
// via https://v2.vuejs.org/v2/guide/components.html#One-Way-Data-Flow
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
So in my code I mimicked those instructions here.
However data() in Note.vue isn't being updated even though the prop value is received according to vue-devtools.
Haven't had success setting the values with the mounted or created lifescyle methods.
When I use static data, this seems to work fine, how can I ensure the child component reacts to receiving props when it comes from a remote source?
When you are passing initialNote as prop for initial value, but I see initialNote is being populated asynchronously in getNote method, so it will not be present initially when the component will be mounted. It will be populated after some time by the time initialisation would have already happened.
In the example give in vue documentation, initialCounter is static value which will perfect as it will have same value from beginning.

When to use state and when props?

I am studying the principles of react.
According to some reviews, some people says is better to keep your component stateless, what does it mean?
But other people says, that if you need to update your component, then you should learn how to set your state to the proper state.
I saw this.props / this.setProps and this.state / this.setState and I am confuse with that.
Something I am trying to figure is, how can I update a component by itself and not from a parent component? should I use props or state in this case?
I already read some docs about props and state, what I don't have clear, is: when to use one or another ?
Props vs. state comes down to "who owns this data?"
If data is managed by one component, but another component needs access to that data, you'd pass the data from the one component to the other component via props.
If a component manages the data itself, it should use state and setState to manage it.
So the answer to
how can I update a component by itself and not from a parent component? should I use props or state in this case?
is to use state.
Props should be considered immutable and should never be changed via mutation. setProps is only useful on a top-level component and generally should not be used at all. If a component passes another component a property, and the first component wants the second to be able to change it, it should also pass it a function property that the second component can call to ask the first component to update its state. For example:
var ComponentA = React.createClass({
getInitialState: function() {
return { count: 0 };
},
render: function() {
return <Clicker count={this.state.count} incrementCount={this.increment} />;
},
increment: function() {
this.setState({count: this.state.count + 1});
}
});
// Notice that Clicker is stateless! It's only job is to
// (1) render its `count` prop, and (2) call its
// `incrementCount` prop when the button is clicked.
var Clicker = React.createClass({
render: function() {
// clicker knows nothing about *how* to update the count
// only that it got passed a function that will do it for it
return (
<div>
Count: {this.props.count}
<button onClick={this.props.incrementCount}>+1</button>
</div>
);
}
});
(Working example: https://jsbin.com/rakate/edit?html,js,output)
For and object-oriented programming analogy, think of a class/object: state would be the properties you put on the class; the class is free to update those as it sees fit. Props would be like arguments to methods; you should never mutate arguments passed to you.
Keeping a component "stateless" means that it doesn't have any state, and all its rendering is based on its props. Of course, there has to be state somewhere or else your app won't do anything! So this guideline is basically saying to keep as many components as possible stateless, and only manage the state in as few top-level components as possible.
Keeping components stateless makes them easier to understand, reuse, and test.
See A brief interlude: props vs state in the React docs for more information.
Use state when you know the variable value is going to affect the view. This is particularly critical in react, because whenever the state variable changes there is a rerender(though this is optimized with the virtual DOM, you should minimize it if you can), but not when a prop is changed (You can force this, but not really needed).
You can use props for holding all other variables, which you think can be passed into the component during the component creation.
If you have want to make a multi-select dropdown called MyDropdown for example
state = {
show: true,
selected:[],
suggestions:this.props.suggestionArr.filter((i)=>{
return this.state.suggestions.indexOf(i)<0;
})
}
props={
eventNamespace:'mydropdown',
prefix : 'm_',
suggestionArr:[],
onItemSelect:aCallbackFn
}
As you can see, the objects in the state variable are going to affect the view some way or the other.
The objects in the props are mostly objects which should remain the same throughout the component life cycle. So these objects can be callback functions, strings used to namespace events or other holders.
So if you do want to update the component by itself, you need to have to look into how componentWillRecieveProps ,componentWillUpdate, componentDidUpdate and componentShouldUpdate works. More or less, this depends on the requirement and you can use these lifecycle methods to ensure that the rendering is within the component and not in the parent.

Categories