React Hooks:在componentDidMount上发布一个动作

问题描述 投票:0回答:1

我有三个页面,PageS,PageS和PageS,它们包含表单元素formField

globalReducer.js中的状态

import { fromJS } from 'immutable';

const initialState = fromJS({
  userInteractionBegun: false,
  pageActive: '',
  refreshData: true,
})

我想调度一个动作,当组件(页面)安装时,将pageActive设置为相应的页面值(A,B或C中的一个),如果formField,则将userInteractionBegun === false刷新为空白。

对于每个页面组件,要从globalReducer获取pageActive中的props状态,我这样做,

function PageA(props) {
  //.....
}

// globalState is defined in conigureStore, I am using immutable.js. Link provided below this code.
const mapStateToProps = state => ({
  pageActive: state.getIn(['globalState', 'pageActive']),
})

export default connect(mapStateToProps, null)(PageA);

链接到immutable.js getIn()

store.js

import globalReducer from 'path/to/globalReducer';

const store = createStore(
  combineReducers({
    globalState: globalReducer,
    //...other reducers
  })
)

我想抽象逻辑来在每次组件(页面)安装时更新pageActive

我知道如何使用HOC来抽象这个逻辑,但我不知道如何使用react hooks来做,所以每次pageA,pageB或pageC安装时,调度setPageActive的动作,如果formFielduserInteractionBegun被设置为空白是假的。


例如,我会在pageA.js中进行

import usePageActive from 'path/to/usePageActive';

const [pageActive, setPageActive] = useReducer(props.pageActive);
usePageActive(pageActive);

然后在usePageActive.js中

export default usePageActive(pageActive) {
  const [state, setState] = useState(pageActive);
  setState(// dispatch an action //)
}
javascript reactjs
1个回答
0
投票

我没有太多时间将脚趾浸入反应钩中,但在阅读完文档并使用它一分钟之后,我认为这样做会有所帮助。我在这里使用内置状态,但你可以在效果中使用redux或其他任何你喜欢的东西。你可以看到这个代码的工作示例here诀窍是使用钩子创建器来创建自定义钩子。这样,父级和子级可以保持对同一状态的引用,而不会影响父级的useEffect。

import React, { useState, useEffect } from 'react';
import ReactDOM from "react-dom";

const activePageFactory = (setActivePage) => (activePage) => {
  useEffect(() => {
    setActivePage(activePage)
    return () => {
      setActivePage('')
    }
  }, [activePage])
  return activePage
}

function App() {
  const [activePage, setActivePage] = useState('');
  const [localPage, setLocalPage] = useState('Not Selected');
  const selectedPage = () => {
    switch(localPage) {
      case 'A':
        return <PageA useActivePage={activePageFactory(setActivePage)}  />
      case 'B':
        return <PageB useActivePage={activePageFactory(setActivePage)}  />
      default:
        return null;
    }
  }
  return (
    <div>
      <p>Active page is {activePage}</p>
      <button onClick={() => setLocalPage('A')}>
        Make A Active
      </button>
      <button onClick={() => setLocalPage('B')}>
        Make B Active
      </button>
      {
        selectedPage()
      }
    </div>
  );
}

function PageA({useActivePage}) {
  useActivePage('A');
  return (
    <div>
      <p>I am Page A</p>
    </div>
  )
}

function PageB({useActivePage}) {
  useActivePage('B');
  return (
    <div>
      <p>I am Page B</p>
    </div>
  )
}
© www.soinside.com 2019 - 2024. All rights reserved.