使用Redux与React挂钩连接

时间:2020-05-25 04:01:00

标签: reactjs redux react-redux react-hooks

这不是关于像useSelectoruseDispatch这样的react-redux钩子的问题。我很好奇,想知道老式的带有功能组件的react-redux connect()以及在此示例中何时需要使用诸如useEffect之类的React钩子。

假设我有这个功能组件,如果存在someReduxData,则该组件以绿色渲染“ Hello world”,否则,将其渲染为红色。

const RandomComponent = ({ someReduxData }) => {
  const style = {
    color: someReduxData ? "green" : "red";
  }; 

  return (
    <div style={style}>Hello world</div>
  );
}

const mapStateToProps = (state) => {
  return {
    someReduxData: state.someReduxData;
  };
};

export default connect(mapStateToProps)(RandomComponent);

假设组件首次安装到DOM时,someReduxData为空。然后,它更改状态,因此不再为null。这是否会强制重新渲染RandomComponent,使其呈现绿色?如果不是,那么我假设我需要用someReduxData来监听useEffect()上的更改?

1 个答案:

答案 0 :(得分:1)

这将强制重新渲染RandomComponent。无论类与功能组件如何,connect的工作原理都是相同的。

下面是一个使用功能组件的示例:在调度动作之前,有2秒钟的setTimeout使App div变为绿色。

还有一个使用钩子代替connect的相同组件的示例。

connect和hook之间的主要区别在于,connect实际上充当组件的React.memo。可以使用布尔标志将其关闭,但您可能永远不必这样做:https://react-redux.js.org/api/connect#pure-boolean

const initialstate = {
  someReduxData: null,
};

const reducer = (state = initialstate, action) => {
  switch (action.type) {
    case 'action':
      return {
        someReduxData: action.data,
      };
    default:
      return initialstate;
  }
};

const actionCreator = (data) => {
  return {
    type: 'action',
    data,
  };
};

const store = Redux.createStore(reducer);

const App = ({ someReduxData }) => {
  return (
    <div className={someReduxData}>
      Some div -- Will turn green in 2 seconds
    </div>
  );
};

const mapStateToProps = (state) => {
  return {
    someReduxData: state.someReduxData,
  };
};

const WrappedApp = ReactRedux.connect(mapStateToProps)(App);

const AppWithHooks = () => {
  const someReduxData = ReactRedux.useSelector(state=>state.someReduxData);
  return (
    <div className={someReduxData}>
      Some div with a hook -- Will turn green in 2 seconds
    </div>
  );
};

ReactDOM.render(
  <ReactRedux.Provider store={store}>
    <WrappedApp />
    <AppWithHooks />
  </ReactRedux.Provider>,
  document.querySelector('#root')
);

setTimeout(() => store.dispatch(actionCreator('green')), 2000);
.green {
  background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js" integrity="sha256-7nQo8jg3+LLQfXy/aqP5D6XtqDQRODTO18xBdHhQow4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js" integrity="sha256-JuJho1zqwIX4ytqII+qIgEoCrGDVSaM3+Ul7AtHv2zY=" crossorigin="anonymous"></script>

<div id="root" />