【问题标题】:React context: consumer do not trigger handlers from provider反应上下文:消费者不会从提供者触发处理程序
【发布时间】:2023-03-04 14:36:01
【问题描述】:

我有以下情况: 为我的组件提供状态的提供程序:ChildProvider 和许多消费者:ChildrenComponentChildrenListComponent 等。在提供程序中,我设置了处理程序来处理列表上的添加、编辑和删除项目,我还设置了处理程序处理显示或隐藏组件以及每个 si 的子列表。我可以完全按照预期看到提供者提供的列表,但处理程序不起作用。例如,在 childrenlist 组件中,我发送处理程序以根据 TitleComponent 中的按钮单击显示 AddChildComponent,但我看不到 ChildrenAddComponent 渲染,我不知道为什么。我在这里想念什么?它也可以工作的任何其他处理程序:(

MilesContext

import React from 'react';

const MilesContext = React.createContext();

export default MilesContext;

ChildrenProvider

import MilesContext from './MilesContext';
import React, {Component} from 'react';

export default class ChildProvider extends Component {

    state = {
        child: {
            childList : [{
                id: 1,
                name: "Sheldon Lee Cooper",
                birthDate: "01-25-2014",
                gender: "male"

            },
            {
                id: 2,
                name: "Amy Farah Fowler",
                birthDate: "06-25-2017",
                gender: "female"
            }],
            showComp : false,
            handleShow : this.handleShowComponent,
            handleHide : this.handleHideComponent,
            handAddChildren : this.handleAddChildrenToList,
            handleEditChildren : this.handleEditChildrenFromList,
            handleDeleteChildren: this.handleDeleteChildrenFromList
        }
    }

    handleShowComponent = () => {
        console.log("eliete")
        this.setState({ showComp : true})
    }
    handleHideComponent = () => this.setState({ showComp : false})
    handleAddChildrenToList = (child) => {
        child.id = this.state.child.childList.length + 1
        this.setState({
            childList: [...this.state.child.childList, child]
        })
    }
    handleEditChildrenFromList = (editedChild) => {
        const editedList = this.state.child.childList.map(child => (child.id === editedChild.id ? editedChild : child))
        this.setState({childList: editedList})
    }
    handleDeleteChildrenFromList = (deletedChild) => {
        const editedList = this.state.child.childList.filter(child => child.id !== deletedChild.id)
        this.setState({childList: editedList})
    }

    render() {
        return (
            <MilesContext.Provider
                value={{
                    child: this.state.child,
                    handleShowComponent : this.state.child.handleShow,
                    handleHideComponent : this.state.child.handleHide,
                    handleAddChildrenToList : this.state.child.handAddChildren,
                    handleEditChildrenFromList : this.state.child.handleEditChildren,
                    handleDeleteChildrenFromList: this.state.child.handleDeleteChildren
                }}>
                {this.props.children}
            </MilesContext.Provider>
        );
    }

}

子组件

import React from 'react';
import MilesContext  from '../../context/MilesContext';
import ChildrenList from './ChildrenListComponent';
import ChildrenAddComponent from './ChildrenAddComponent';

const Children = () => (
    <MilesContext.Consumer>
        {(value) => (
            <>
                <ChildrenList />
                { value.child.showComp ?
                    <ChildrenAddComponent/>
                    :
                    null
                }
            </>
        )}
    </MilesContext.Consumer>
)

export default Children;

子组件

import React from 'react';
import MilesContext  from '../../context/MilesContext';
import ChildrenItem from './ChildrenItem';
import TitleComponent from '../TitleComponent';

const ChildrenList = (props) => (
    <MilesContext.Consumer>
        {value => (
            <div className="container-wrapper">
                <div className="row">
                    <TitleComponent 
                        title={ "Children" } 
                        icon={ "fa fa-plus-circle fa-2x justify-content-center mx-auto top-right" }
                        showComponent={ value.child.handleShowComponent } 
                    />
                </div>
                <div className="row justify-content-center">
                    { value.child.childList.length === 0 ?
                        <div className="col-sm-3">
                            <div className="card bg-warning text-center pt-3">
                                <p>No child added!</p>
                            </div>
                        </div>
                        : 
                        <div className="col-sm-6">
                            <ul className="list-unstyled">
                                { value.child.childList.map(child => {
                                    console.log(value.child.handleDeleteChildren)
                                    return (
                                        <li key={ child.id }>
                                            <ChildrenItem
                                                child={ child }
                                                handleEditChildren={ value.child.handleEditChildren }
                                                handleDeleteChildren={ value.child.handleDeleteChildren }
                                            />
                                        </li>
                                    )})
                                }
                            </ul>
                        </div>
                    }
                </div>
            </div>
        )}
    </MilesContext.Consumer>
)

export default ChildrenList;

TitleComponet

import React from 'react';
import MilesContext  from '../context/MilesContext';

export default function TitleComponent(props) {

    return (
        <MilesContext.Consumer>
            { value => (
                <div className="col-sm-12 title-container">
                    <h3><i className="fa fa-user fa-1x mr-3"></i>{props.title}</h3>
                    <i className={props.icon} onClick={() => props.showComponent}></i>
                    <hr/>
                </div>
            )}
        </MilesContext.Consumer>
    );
}

【问题讨论】:

    标签: reactjs state provider consumer


    【解决方案1】:

    问题来自"different state level"

    handleShowComponent = () => {
        console.log("eliete")
        this.setState({ showComp : true})
    }
    

    这在this.state.showComp 上运行,而不是在this.state.child.showComp 上运行,您[可能] 在这里期待

                { value.child.showComp ?
    

    或这里

            <MilesContext.Provider
                value={{
                    child: this.state.child,
    

    如果您想更新嵌套对象,请记住不要改变现有对象 (child),而是返回一个新对象:

    setState( { child: {...this.state.child, showComp: true } })
    

    更多关于here

    Google 获取其他 setState 深层对象更新示例...或与 redux 相关的...同样的规则适用(浅比较)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      • 2020-03-02
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多