最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to update react context provider state on button click - Stack Overflow

programmeradmin5浏览0评论

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;

UpdateBtn.js

const UpdateBtn = () => {

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

export default UpdateBtn;

How do I update the inputAmount state present in WebContext.js on button click in UpdateBtn.js? App.js is the parent ponent for UpdateBtn.js Also, How can I convert the WebContext.js into a functional ponent?

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;

UpdateBtn.js

const UpdateBtn = () => {

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

export default UpdateBtn;

How do I update the inputAmount state present in WebContext.js on button click in UpdateBtn.js? App.js is the parent ponent for UpdateBtn.js Also, How can I convert the WebContext.js into a functional ponent?

Share Improve this question asked Sep 11, 2019 at 12:17 mevrickmevrick 1,0454 gold badges21 silver badges31 bronze badges 1
  • 2 There are perfect examples for this on the official React documentation: reactjs/docs/… – Andre Commented Sep 11, 2019 at 12:22
Add a ment  | 

2 Answers 2

Reset to default 5

You should pass the function in Provider which you can call to update the value: 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;

UpdateBtn.js

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

export default UpdateBtn;

or

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;

An alternative approach might be to use a reducer to update your state. For example:

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 those into your provider file:

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

and use useReducer to create a store:

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

You can then import the context into the ponent that needs it and use useContext to get at the state and dispatch method. On the click of the button you can dispatch a new value to the store to update 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>
  );
};

I've created a full demo to show you how it works in harmony.

发布评论

评论列表(0)

  1. 暂无评论