Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.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
Javascript 反应-什么';受控组件的好处是什么?_Javascript_Reactjs - Fatal编程技术网

Javascript 反应-什么';受控组件的好处是什么?

Javascript 反应-什么';受控组件的好处是什么?,javascript,reactjs,Javascript,Reactjs,假设我们有一个名为MyChildComponent的组件,用于显示数字列表,还可以通过MyChildComponent内的按钮单击将随机数添加到列表中。当按钮单击时,只有MyChildComponent得到重新渲染,因为只有MyChildComponent的状态得到更新 public class MyParentComponent extends React.Component { const numsInParent = [0,1,2]; render() {

假设我们有一个名为MyChildComponent的组件,用于显示数字列表,还可以通过MyChildComponent内的按钮单击将随机数添加到列表中。当按钮单击时,只有MyChildComponent得到重新渲染,因为只有MyChildComponent的状态得到更新

public class MyParentComponent extends React.Component {
    const numsInParent = [0,1,2];
    render() {
        return <MyChildComponent nums="numsInParent " />);
    }
}
public class MyChildComponent extends React.Component {
    const { nums } = this.props;
    state = { nums: this.props.nums };
    handleChange = ()=> {
        this.setState({ nums: {...nums, random()} });
    };
    render() {
       return (
           <button onClick="this.handleChange">Add<button>
           <ul>
                nums.map((num) =><li>{num}</li>)
           </ul>);
    }
}
这样做,当在子组件内单击按钮时,将导致父组件和子组件都以child->parent->child的方式重新渲染,对吗?那么,这种设计比第一种设计有什么好处呢?它会对性能造成影响吗?我见过一个示例项目,它的结构如下

ComponentA(实际方法)->ComponentB->ComponentC->。。。ComponentX


为了弄清楚ComponentX中的某些内容是如何更改的,我们需要一直到ComponentA中声明的实际方法的位置,这是否也意味着当ComponentX中触发某些更改时,从A、B、C到X的所有组件都将得到重新渲染?值得吗?

关于将状态置于父对象中使其成为受控组件的声明与受控和非受控组件无关。受控组件是允许React在内部处理表单数据的组件,而非受控组件是将表单数据存储在DOM中的组件。因此,由于您在React的内部状态中存储所有内容的数据,因此始终在创建受控组件

但是,要回答将该状态存储在何处的问题,只有当父级需要访问信息时,将该状态存储在父级中才有用。根据React文档和React指南,始终使用尽可能少的状态,并始终将状态推至所需的最低点

查看您的代码,有人告诉您所做的是错误的,原因是您从父级传递了一个道具,然后使用该道具填充状态。这可以创建一个指向数组的指针,并且您在子对象中更改的任何值都将更新父对象的道具,这将导致同步问题。因为您的父母不需要知道状态,所以不需要将初始值传递给孩子。要修复代码,它应该更像这样:

public class MyParentComponent extends React.Component {
    render() {
        return <MyChildComponent />);
    }
}

public class MyChildComponent extends React.Component {
    state = { nums: [0,1,2]};
    handleChange = ()=> {
        this.setState({ nums: [...nums, random()] });
    };
    render() {
       return (
           <button onClick="this.handleChange">Add<button>
           <ul>
                nums.map((num) =><li>{num}</li>)
           </ul>);
    }
}
公共类MyParentComponent扩展了React.Component{
render(){
返回);
}
}
公共类MyChildComponent扩展了React.Component{
状态={nums:[0,1,2]};
handleChange=()=>{
this.setState({nums:[…nums,random()]});
};
render(){
返回(
添加
    nums.map((num)=>
  • {num}
); } }
父级需要了解其子级也需要了解的状态的唯一原因是父级是否需要访问该状态以及子级(在某些情况下,您可能希望基于状态控制父级功能,而子级也需要基于相同状态更改其功能)

否则,您是正确的,父对象和子对象都将执行重新渲染。对于父级,这是一个浪费的渲染,不需要执行,因为父级没有任何更改。只有子级需要重新渲染


这是一个关于优化的主题,并且只有在子对象中才有状态比在父对象中有更好的性能优化。你会用你的眼睛注意到区别吗,不太可能。但是,将状态设置为正确的级别可以优化组件并使其更高效。

“ComponentA,这是否也意味着当在ComponentX中触发某些更改时,从A、B、C到X的所有组件都将得到重新渲染?”->是,除非您将其记住,或使用
React.memo
。这是一个每个人都有自己观点的问题,就像全球对地方政府一样。就我个人而言,我会问“纯语义上,这些信息最好归属于哪里?”并相应地写下我的摘要。
就我个人而言,我会问“纯语义上,这些信息最好归属于哪里?”并相应地写下我的摘要。
这是一个很好的建议!我总是这样做。如果你的父母不需要知道这些信息,那么为什么要提供给他们呢。关注点分离。这是否回答了您的问题?谢谢!很高兴知道
这是一个关于优化的主题,我认为这是React中必须遵循的某种设计模式,所以我有点困惑,因为其他评论员质疑我这不是一个好的方法。即使在我的工作中,我的父组件不需要关心我的子组件更改数据的内容或方式,它的所有工作都是获取数据并将其传递给子组件,但我被要求在父组件中实现数据更新逻辑,而不是在childRight中实现数据更新逻辑,因此,您的家长需要了解数据,以便更新数据并调用以在加载中获得新结果。因此,您希望将您的状态向上移动到父级。在这种情况下,这是一个很好的例子,说明父级需要了解数据的位置。
public class MyParentComponent extends React.Component {
    render() {
        return <MyChildComponent />);
    }
}

public class MyChildComponent extends React.Component {
    state = { nums: [0,1,2]};
    handleChange = ()=> {
        this.setState({ nums: [...nums, random()] });
    };
    render() {
       return (
           <button onClick="this.handleChange">Add<button>
           <ul>
                nums.map((num) =><li>{num}</li>)
           </ul>);
    }
}