如何在 React 的 Context 中传递函数?

Fai*_*ire 2 reactjs

我创建了一个上下文(CharacterContext),它导出类CharacterProvider,它本身将状态中的几个对象传递给消费者。我还想传递一个 REST 调用函数 getCharacter。我正在考虑像这样传递它:


export class CharacterProvider extends Component {
    constructor(props) {
        super(props);

        this.state = {
            name: "",
            ...
            getCharacter: this.getCharacter(),
        }
    }

    getCharacter = (id) => {
        console.log("Getting the character...")
        CharacterDataService.getCharacterById(id)
            .then(
                response => {
                    console.log(response);
                    this.setState({
                        name: response.data.username,
                        ...
                    });
                }
            )
    }

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

export const CharacterConsumer = CharacterContext.Consumer
Run Code Online (Sandbox Code Playgroud)

不过我想这只会触发函数并传递结果。传递函数的正确方法是什么?到目前为止,元素已经收到了 props 中的函数,如下所示:

export default class Loader extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            names: [/* filled by an API call */]
        }
        ....

    render() {
        return (
            <div className="row mt-3">
                    <div className="col"></div>
                    {
                        Object.values(this.state.names).map( (name) => {
                            return(
                            <div className="col-1" key={name}>

                                <button className="btn btn-info" onClick={() =>
                                    this.props.getCharacter(Object.keys(this.state.names).find(key => this.state.names[key] === name))} key={name}>
                                {name}
                                </button>
                            </div>
                        )})
                    }
                    <div className="col"></div>

                </div>
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

我想从上下文传递该函数,因为它也将在几个不同的组件中使用。我已经使用竞赛成功地传递了值,但我仍在寻找传递函数的正确方法,并且到目前为止我发现没有教程能够真正帮助我。

抱歉,如果代码不稳定,我最近刚刚开始使用 ReactJS 和 JS 本身。

编辑:

我这样传递提供商:

App.js
...
render() {
        return (
            <div className="App container-fluid">
                <CharacterProvider>
                    <Loader/>
                </CharacterProvider>
...


Run Code Online (Sandbox Code Playgroud)

Shu*_*tri 5

您没有正确使用上下文。您需要渲染Provider并将其包装在层次结构中

export class CharacterProvider extends Component {
    constructor(props) {
        super(props);

        this.state = {
            name: "",
            ...
            getCharacter: this.getCharacter(),
        }
    }

    getCharacter = (id) => {
        console.log("Getting the character...")
        CharacterDataService.getCharacterById(id)
            .then(
                response => {
                    console.log(response);
                    this.setState({
                        name: response.data.username,
                        ...
                    });
                }
            )
         render() {
              return (
                   <CharacterContext.Provider value={this.state}>{children}</CharacterContext.Provider>
              )
          }
    }

export const CharacterConsumer = CharacterContext.Consumer
Run Code Online (Sandbox Code Playgroud)

不是你CharacterProvider在层次结构中渲染它,比如

return (
    <CharacterProvider>
         <Loader/>
    </CharacterProvider>
)
Run Code Online (Sandbox Code Playgroud)

现在您需要为 Loader 指定 contextTypes 并使用以下函数this.context

export default class Loader extends React.Component { 
    static contextTypes = CharacterContext
    constructor(props) {
        super(props);
        this.state = {
            names: [/* filled by an API call */]
        }
        ....

    render() {
        return (
            <div className="row mt-3">
                    <div className="col"></div>
                    {
                        Object.values(this.state.names).map( (name) => {
                            return(
                            <div className="col-1" key={name}>

                                <button className="btn btn-info" onClick={() =>
                                    this.context.getCharacter(Object.keys(this.state.names).find(key => this.state.names[key] === name))} key={name}>
                                {name}
                                </button>
                            </div>
                        )})
                    }
                    <div className="col"></div>

                </div>
        )
    }
}
Run Code Online (Sandbox Code Playgroud)