ReactJs context - how to replace the current compo

2019-06-09 14:30发布

I am trying to get my head around ReactJs context, and have finally made some progress to display the state name and countNumber.

However I am still struggling to work out how to replace the current state, which is used in my formatCount() function.

Can anyone let me know how you would do this in my example below?

I would like to use the number in my context e.g. 5 in the method, formatCount(), so it would be something like

    formatCount() {
        const currentCount = {c.state.currentCount};
        return currentCount === 0 ? "Zero" : currentCount;
    }

enter image description here

Here is my context

import React, { Component } from "react";
export const CounterContext = React.createContext();

export default class CounterProvider extends Component {
    state = {
        state: { name: 'bob', currentCount: 5 },
    }
    render() {
        return (
            <CounterContext.Provider value={ this.state }>
                {this.props.children}
            </CounterContext.Provider>
        )
    }
}

Here is my counter component

import React, { Component } from "react";
import { RouteComponentProps } from "react-router";
import { CounterContext } from "../contexts/context.js";

export class Counter extends Component {
    state = { currentCount: 7 }

    render() {
        return <div className="m-2">
            <CounterContext.Consumer>
                {c =>
                    <div className="m-2">
                        <p>My name is {c.state.name} - {c.state.currentCount}</p>
                        <span className={this.getBadgeClasses()}>{this.formatCount()}</span>
                        <button className="btn btn btn-primary btn-sm m-2" onClick={() => { this.incrementCounter() }}>Increment</button>
                        <button className="btn btn-danger btn-sm m-2" onClick={() => { this.incrementCounter() }}>Delete</button>
                    </div>
                }
            </CounterContext.Consumer>
        </div>;
    }

    formatCount() {
        const currentCount = this.state.currentCount;
        return currentCount === 0 ? "Zero" : currentCount;
    }

    getBadgeClasses() {
        let classes = "badge m-2 badge-";
        classes += this.state.currentCount === 0 ? "warning" : "primary";
        return classes;
    }

    incrementCounter() {
        this.setState({
            currentCount: this.state.currentCount + 1
        });
    }
}

2条回答
走好不送
2楼-- · 2019-06-09 15:11

I'm not quite sure of your usage of CounterContext here, so sorry if I've misread the question.

When you say 'state passed down' - do you mean you're attempting to update the state and display the updated state?

To do so you'll need to initialise your state with a constructor:

constructor() {
    super();
    this.state = {
      currentCount: 7
    };
  };

You can then update state with this.setState({}) as you have.

查看更多
The star\"
3楼-- · 2019-06-09 15:21

The first step is to move the method you want to call (the one that updates the state) to the CounterProvider class. Then pass the method into the state object. After doing that you can now update your Counter class to something like so:

<CounterContext.Consumer>
   {(c, methodName) =>
     <div className="m-2">
         My name is {c.state.name}
         <button onClick={methodName}></button>
     </div>
   }
</CounterContext.Consumer>

Please note that I have used methodeName and removed modified the CounterContext.Consumer component in order to simplify things.

You can read more about the Context API: https://reactjs.org/docs/context.html

查看更多
登录 后发表回答