如何在React的上下文中传递函数?

时间:2019-05-09 08:01:10

标签: 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

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


1 个答案:

答案 0 :(得分:2)

您没有正确使用上下文。您需要呈现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>
        )
    }
}