【问题标题】:How to update react context provider state on button click如何在按钮单击时更新反应上下文提供程序状态
【发布时间】:2019-09-11 12:17:35
【问题描述】:

WebContext.js

import React, { createContext, Component } from 'react';

export const WebContext = createContext();

class WebContextProvider extends Component {
    state = {
        inputAmount: 1,
    };

    render() {
        return <WebContext.Provider value={{ ...this.state }}>{this.props.children}</WebContext.Provider>;
    }
}

export default WebContextProvider;

App.js

const App = () => {

return (
        <WebContextProvider>
            <UpdateBtn />
        </WebContextProvider>
    );
};

export default App;

更新Btn.js

const UpdateBtn = () => {

return (
        <Div>
            <Button onClick={} />
        </Div>
    );
};

export default UpdateBtn;

如何在 UpdateBtn.js 中单击按钮时更新 WebContext.js 中的 inputAmount 状态? App.jsUpdateBtn.js 的父组件另外,如何将 WebContext.js 转换为功能组件?

【问题讨论】:

标签: javascript reactjs material-ui jsx


【解决方案1】:

您应该传递 Provider 中的函数,您可以调用该函数来更新值: WebContext.js


import React, { createContext, Component } from 'react';

export const WebContext = createContext();

class WebContextProvider extends Component {
    state = {
        inputAmount: 1,
    };

    render() {
        return (
            <WebContext.Provider
                value={{
                    data: ...this.state, // all data now in context.data field
                    update: () => { // we added this callback
                        this.setState((state) => ({
                            inputAmount: state.inputAmount + 1,
                        }));
                    },
                }}
            >
                {this.props.children}
            </WebContext.Provider>
        );
    }
}

export default WebContextProvider;

App.js

const App = () => {

return (
        <WebContextProvider>
            <UpdateBtn />
        </WebContextProvider>
    );
};

export default App;

更新Btn.js

const UpdateBtn = () => {
const context = useContext(WebContext); // we use hook to get context value
return (
        <Div>
            <Button onClick={context.update} /> 
        </Div>
    );
};

export default UpdateBtn;

const UpdateBtn = () => {

// or we can use Consumer to get context value
return (
        <Div>
            <WebContext.Consumer>
              {context => <Button onClick={context.update} />}
            </WebContext.Consumer>
        </Div>
    );
};

export default UpdateBtn;

【讨论】:

【解决方案2】:

另一种方法可能是使用 reducer 来更新您的状态。例如:

export const initialState = {
  inputValue: 1
}

export function reducer(state, action) {
  const { type, payload } = action;
  switch (type) {
    case 'updateInputValue': {
      return { ...state, inputValue: payload };
    }
    default: return state;
  }
}

将它们导入您的提供程序文件:

import { initialState, reducer } from './reducer';

并使用useReducer 创建商店:

export function WebContextProvider({ children }) {
  const store = useReducer(reducer, initialState);
  return (
    <WebContext.Provider value={store}>
      {children}
    </WebContext.Provider>
  );
}

然后您可以将上下文导入到需要它的组件中,并使用useContext 来获取状态和调度方法。单击按钮后,您可以向商店发送一个新值以更新inputValue

export default function UpdateButton() {

  const [ { inputValue }, dispatch ] = useContext(WebContext);

  function handleClick(e) {
    dispatch({
      type: 'updateInputValue',
      payload: inputValue + 1
    });
  }

  return (
    <div>
      <div>{inputValue}</div>
      <button onClick={handleClick}>Click</button>
    </div>
  );
};

我创建了a full demo 来向您展示它是如何协调工作的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 2021-06-09
    相关资源
    最近更新 更多