Home  >  Article  >  Web Front-end  >  What is the relationship between react, redux and react-redux?

What is the relationship between react, redux and react-redux?

不言
不言forward
2018-11-26 14:59:412530browse

This article brings you what is the relationship between react, redux and react-redux? , has certain reference value, friends in need can refer to it, I hope it will be helpful to you.

React

For some small projects, only using React is enough. Props and state can be used for data management. So when do you need to introduce Redux? ? When the data for rendering a component is obtained from the parent component through props, it is usually A --> B, but as the business complexity increases, it may be like this: A --> B -- > C --> D --> E, the data required by E needs to be passed from A through props, and the corresponding E --> A reversely passes the callback. The component BCD does not need these data, but it must be passed through them, which is indeed a bit unpleasant, and the passed props and callbacks will also affect the reuse of the BCD component. Or if sibling components want to share certain data, it is not very convenient to transfer or obtain it. In situations like this, it is necessary to introduce Redux.

Actually A --> B --> C --> D --> E In this case, React can get the data without passing props layer by layer. Just use Context. . The react-redux that will be discussed later uses Context to allow each sub-component to get the data in the store.

Redux

In fact, we just want to find a place to store some shared data. Everyone can get it and modify it, that's all. Is it okay to put it in one all variables? Yes, of course it works, but it is too inelegant and unsafe because it is a global variable that can be accessed and modified by anyone. It may be accidentally overwritten by a friend. If global variables don't work, just use private variables. Private variables cannot be modified easily. Do you immediately think of closures...

Now we need to write such a function, which satisfies:

Storing a data object
The outside world can access this data
The outside world can also modify this data
When the data changes, the subscriber is notified

function createStore(reducer, initialState) {
 // currentState就是那个数据
 let currentState = initialState;
 let listener = () => {};
 
 function getState() {
 return currentState;
 }
 function dispatch(action) {
 currentState = reducer(currentState, action); // 更新数据
 listener(); // 执行订阅函数
 return action;
 }
 function subscribe(newListener) {
 listener = newListener;
 // 取消订阅函数
 return function unsubscribe() {
  listener = () => {};
 };
 }
 return {
 getState,
 dispatch,
 subscribe
 };
}
 
const store = createStore(reducer);
store.getState(); // 获取数据
store.dispatch({type: 'ADD_TODO'}); // 更新数据
store.subscribe(() => {/* update UI */}); // 注册订阅函数

Steps to update the data:

What: What do you want to do--- dispatch(action)
How: How to do it, the result--- reducer(oldState, action) => newState
Then?: Re-execute the subscription function (Such as re-rendering the UI, etc.)
This implements a store and provides a data storage center for external access, modification, etc. This is the main idea of ​​Redux. Therefore, Redux does not have any essential relationship with React. Redux can be used normally in combination with other libraries. It’s just that the data management method of Redux is very consistent with the data-driven view concept of React. The combination of the two makes development very convenient.

Now that we have a safe place to access data, how can we integrate it into React? We can create a window.store = createStore(reducer) when the application is initialized, and then obtain data through store.getState() where needed, update the data through store.dispatch, and subscribe to data changes through store.subscribe. Then perform setState... If you do this in many places, it will be really overwhelming, and it still does not avoid the inelegance of global variables.

React-Redux

Since global variables have many shortcomings, let’s change the idea and integrate the store directly into the top-level props of the React application. As long as each sub-component It is enough to have access to the top-level props, such as this:

<TopWrapComponent store={store}>
 <App />
</TopWrapComponent>,

React just provides such a hook, Context, and its usage is very simple. You will understand it by taking a look at the official demo. Now that each sub-component can easily access the store, the next step is for the sub-component to take out the data used in the store, modify it, and subscribe to update the UI, etc. Each subcomponent needs to do this again. Obviously, there must be a more convenient way: higher-order components. By encapsulating store.getState(), store.dispatch, and store.subscribe through high-order components, the subcomponents have no awareness of the store. The subcomponents normally use props to obtain data and callbacks to trigger callbacks, which is equivalent to the existence of no store. .

The following is the rough implementation of this high-order component:

function connect(mapStateToProps, mapDispatchToProps) {
 return function(WrappedComponent) {
 class Connect extends React.Component {
  componentDidMount() {
  // 组件加载完成后订阅store变化,如果store有变化则更新UI
  this.unsubscribe = this.context.store.subscribe(this.handleStoreChange.bind(this));
  }
  componentWillUnmount() {
  // 组件销毁后,取消订阅事件
  this.unsubscribe();
  }
  handleStoreChange() {
  // 更新UI
  this.forceUpdate();
  }
  render() {
  return (
   <WrappedComponent
   {...this.props}
   {...mapStateToProps(this.context.store.getState())} // 参数是store里面的数据
   {...mapDispatchToProps(this.context.store.dispatch)} // 参数是store.dispatch
   />
  );
  }
 }
 Connect.contextTypes = {
  store: PropTypes.object
 };
 return Connect;
 };
}
使用connect的时候,我们知道要写一些样板化的代码,比如mapStateToProps、mapDispatchToProps这两个函数:


const mapStateToProps = state => {
 return {
 count: state.count
 };
};
 
const mapDispatchToProps = dispatch => {
 return {
 dispatch
 };
};
 
export default connect(mapStateToProps, mapDispatchToProps)(Child);
 
// 上述代码执行之后,可以看到connect函数里面的
 <WrappedComponent
 {...this.props}
 {...mapStateToProps(this.context.store.getState())}
 {...mapDispatchToProps(this.context.store.dispatch)}
 />
 
// 就变成了
 <WrappedComponent
 {...this.props}
 {count: store.getState().count}
 {dispatch: store.dispatch}
 />

// In this way, the props of the sub-component Child have two additional attributes, count and dispatch

// count can be used to render the UI, and dispatch can be used to trigger callbacks

So, is this OK? OK. Generate a data center store through a closure, and then bind this store to the top-level props of React. The sub-components establish contact with the top-level props.store through HOC, and then obtain data, modify data, and update the UI. Here we mainly talk about how the three are connected together. If you want to know more advanced functions, such as redux middleware, reducer splitting, other parameters of connect, etc., you can take a look at the corresponding source code.


The above is the detailed content of What is the relationship between react, redux and react-redux?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete