首页 > 解决方案 > 如何在 React 的上下文中传递函数?

问题描述

我创建了一个上下文 (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

但是我想这只会触发函数并传递结果。传递函数的正确方法是什么?到目前为止,元素已经收到了 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>
        )
    }
}

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

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

编辑:

我正在传递这样的提供者:

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


标签: reactjs

解决方案


您没有正确使用上下文。您需要渲染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

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

return (
    <CharacterProvider>
         <Loader/>
    </CharacterProvider>
)

现在您需要为 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>
        )
    }
}

推荐阅读