Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何在父级状态更改时防止子组件重新渲染_Reactjs_Frontend - Fatal编程技术网

Reactjs 如何在父级状态更改时防止子组件重新渲染

Reactjs 如何在父级状态更改时防止子组件重新渲染,reactjs,frontend,Reactjs,Frontend,我有两个无状态组件和一个有状态组件。在我的有状态组件中,我有一个人员列表,当我单击其中一人时,它会打开一个模式。我基本上将模态的状态存储在有状态组件中,并将值作为道具发送给模态。因此,它在任何时候打开模型并重新渲染所有内容时都会更改状态 如何防止在更改状态后重新呈现无状态类 我在我的无状态组件中尝试了memo,但没有成功 模态分量 const modal = React.memo((props) => { return ( <Modal show={props.sh

我有两个无状态组件和一个有状态组件。在我的有状态组件中,我有一个人员列表,当我单击其中一人时,它会打开一个模式。我基本上将模态的状态存储在有状态组件中,并将值作为道具发送给模态。因此,它在任何时候打开模型并重新渲染所有内容时都会更改状态

如何防止在更改状态后重新呈现无状态类

我在我的无状态组件中尝试了memo,但没有成功

模态分量

const modal = React.memo((props) => {

    return (
    <Modal show={props.show} onHide={props.handleClose} aria-labelledby="contained-modal-title-vcenter"
           centered>
        <Modal.Header closeButton>
            <Modal.Title>Modal heading</Modal.Title>
        </Modal.Header>
        <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
        <Modal.Footer>
            <Button variant="secondary" onClick={props.handleClose}>
                Close
            </Button>
        </Modal.Footer>
    </Modal>
    )
});

export default modal
const model=React.memo((道具)=>{
返回(
模态标题
呜呜,你正在以模态的方式阅读这篇文章!
接近
)
});
导出默认模式
人成分

const person = React.memo((props) => {
    console.log("render");
    return (
        <article className="Person" onClick={props.clicked}>
            <Container>
                <Row>
                    <Col>
                        <p style={{marginBottom: 0 + 'px', marginTop: 1 + 'rem'}}><b>{props.name}</b></p>
                        <div className="Organization-wrapper">
                            <FontAwesomeIcon className="Organization-icon" icon={faBuilding}/><p>{props.company}</p>
                        </div>
                    </Col>
                    <Col>
                        <div>
                            {
                                props.image ?
                                    <img src={props.image} height="50" width="50" className="Person-image"
                                         alt="avatar"/>
                                    : <svg height="50" width="50" className="Person-image">
                                        <rect fill="cornflowerblue" x="0" y="0" height="50" width="50"/>
                                        <text
                                            fill="#ffffff"
                                            fontSize="20"
                                            textAnchor="middle"
                                            x="25"
                                            y="30">{props.first_char.toUpperCase()}</text>
                                    </svg>
                            }
                        </div>
                    </Col>
                </Row>
            </Container>
        </article>
    );
});
class PersonList extends Component {

    state = {
        persons: [],
        show: false
    };


    componentDidMount() {
        axios.get('')
            .then(response => {
                const result = response.data.data.slice(0, 5);
                this.setState({persons: result});
            });
    }

    personSelectedHandler = (id) => {
        this.showModal();
    };

    showModal = () => {
        this.setState({ show: true });
    };

    hideModal = () => {
        this.setState({ show: false });
    };

    render() {
        const persons = this.state.persons.map(person => {

            let avatar;
            if (person.picture_id != null) {
                avatar = person.picture_id.pictures["128"];
            }
            return <ListGroup>
                <ListGroup.Item>
                    <Person
                        key={person.id}
                        name={person.name}
                        company={person.org_id.name}
                        first_char={person.first_char}
                        image={avatar}
                        clicked={() => this.personSelectedHandler(person.id)}
                    />
                </ListGroup.Item>
            </ListGroup>
        });

        return (

            <div className="Wrapper">
                <Modal show = {this.state.show} handleClose = {this.hideModal}/>
                <Header/>
                <div className="Breadcrumb">
                    <h4 className="Breadcrumb-text"><b>People's List</b></h4>
                    <hr/>
                </div>
                {persons}
            </div>
        );
    }

}

export default PersonList;
const person=React.memo((道具)=>{
控制台日志(“呈现”);
返回(

{props.name}

{props.company}

{ 道具,形象? : {props.first_char.toUpperCase()} } ); });
有状态组件

const person = React.memo((props) => {
    console.log("render");
    return (
        <article className="Person" onClick={props.clicked}>
            <Container>
                <Row>
                    <Col>
                        <p style={{marginBottom: 0 + 'px', marginTop: 1 + 'rem'}}><b>{props.name}</b></p>
                        <div className="Organization-wrapper">
                            <FontAwesomeIcon className="Organization-icon" icon={faBuilding}/><p>{props.company}</p>
                        </div>
                    </Col>
                    <Col>
                        <div>
                            {
                                props.image ?
                                    <img src={props.image} height="50" width="50" className="Person-image"
                                         alt="avatar"/>
                                    : <svg height="50" width="50" className="Person-image">
                                        <rect fill="cornflowerblue" x="0" y="0" height="50" width="50"/>
                                        <text
                                            fill="#ffffff"
                                            fontSize="20"
                                            textAnchor="middle"
                                            x="25"
                                            y="30">{props.first_char.toUpperCase()}</text>
                                    </svg>
                            }
                        </div>
                    </Col>
                </Row>
            </Container>
        </article>
    );
});
class PersonList extends Component {

    state = {
        persons: [],
        show: false
    };


    componentDidMount() {
        axios.get('')
            .then(response => {
                const result = response.data.data.slice(0, 5);
                this.setState({persons: result});
            });
    }

    personSelectedHandler = (id) => {
        this.showModal();
    };

    showModal = () => {
        this.setState({ show: true });
    };

    hideModal = () => {
        this.setState({ show: false });
    };

    render() {
        const persons = this.state.persons.map(person => {

            let avatar;
            if (person.picture_id != null) {
                avatar = person.picture_id.pictures["128"];
            }
            return <ListGroup>
                <ListGroup.Item>
                    <Person
                        key={person.id}
                        name={person.name}
                        company={person.org_id.name}
                        first_char={person.first_char}
                        image={avatar}
                        clicked={() => this.personSelectedHandler(person.id)}
                    />
                </ListGroup.Item>
            </ListGroup>
        });

        return (

            <div className="Wrapper">
                <Modal show = {this.state.show} handleClose = {this.hideModal}/>
                <Header/>
                <div className="Breadcrumb">
                    <h4 className="Breadcrumb-text"><b>People's List</b></h4>
                    <hr/>
                </div>
                {persons}
            </div>
        );
    }

}

export default PersonList;
类PersonList扩展组件{
状态={
人员:[],
节目:假
};
componentDidMount(){
axios.get(“”)
。然后(响应=>{
const result=response.data.data.slice(0,5);
this.setState({persons:result});
});
}
personSelectedHandler=(id)=>{
这是showModal();
};
showModal=()=>{
this.setState({show:true});
};
hideModal=()=>{
this.setState({show:false});
};
render(){
const persons=this.state.persons.map(person=>{
让阿凡达;
if(person.picture_id!=null){
阿凡达=person.picture_id.pictures[“128”];
}
返回
this.personSelectedHandler(person.id)}
/>
});
返回(
人民名单

{个人} ); } } 导出默认个人列表;

如果你最终需要<代码> ID>代码>上下文,你可能想考虑使用父母的状态来实现你所追求的,如果你真的想要避免重新渲染。

您还可以将
Person
转换为(纯)类组件,并在该组件内处理回调

最后,如果推到了紧要关头,您必须使用这个内嵌箭头函数,您可以覆盖
React.memo
的比较函数,这大致类似于为类组件定义
组件shouldUpdate


也许还有另一种我不知道的方法可以让这一切顺利进行,但希望这能帮助您理解这个问题,并探索其他解决方案。这里还有一些想法和讨论:

如果您使用hook,您可以将
useCallback()
方法与
Recat.memo
一起使用。 在您的componenet中:

const callBack = useCallback(() => this.personSelectedHandler(person.id),[person.id]);
useCallback((person.id)=>personSelectedHandler(person.id),[person.id])person.id
相同,code>始终返回相同的函数实例。 然后:



使用shouldComponentUpdate生命周期来防止重新渲染感谢您的回答。我将无状态函数组件更改为React.component,并在其中使用了shouldComponentUpdate。我不能让它与其他选项一起工作。没问题,这是一个需要处理的恼人的用例。如果您想继续使用带有
React.memo
的功能组件,我澄清了覆盖React.memo的比较函数的答案。它应该与定义
componentdiddupdate
大致相同(尽管如果组件不应重新渲染,它应该返回相反的值;
true
)。不过,我从未在这个特殊的案例中使用过它,也不确定是否有任何我不知道的陷阱。
const callBack = useCallback(() => this.personSelectedHandler(person.id),[person.id]);
<Person
    ...
    clicked={callBack}
/>