当前位置: 首页 > 知识库问答 >
问题:

使用道具初始设置状态

上官树
2023-03-14

2)有没有另一种方法可以重写这个逻辑而不使用道具来设置状态?

父组件:

class App extends Component {

  constructor(props){
    super(props);
    this.state ={
      todos: []
    }
  }

  componentDidMount() {
    axios.get('https://jsonplaceholder.typicode.com/todos')
    .then(response => {
      this.setState({ todos: response.data })
    });
  }

  render() {
    if(!this.state.todos){
      return <div>Loading...</div>
    }
    return (
        <div className="container">
          <div className="row">
            {
              this.state.todos.map((todo, i) => {
                return (
                  <Todo todo={todo} key={i}/>
                )
              })
            }
          </div>
        </div>
    );
  }
}

子组件

class Todo extends Component{

  constructor(props) {
    super(props);
    var { title, completed, userId } = this.props.todo;
    this.state = { title, completed, userId }
  }
  changeCompletion = () => {
    this.setState({completed: !this.state.completed})
  }

  render() {
    return(
      <div className="col-md-4 col-sm-6">
        <div className={"card card-inverse text-center " + (this.state.completed ? 'card-success' : 'card-danger')}>
          <div className="card-block">
            <blockquote className="card-blockquote">
              <p>{ this.state.title }</p>
            </blockquote>
            <button onClick={this.changeCompletion} className={"btn btn-sm " + (this.state.completed ? 'btn-danger' : 'btn-success')}>{ this.state.completed ? 'incomplete' : 'complete'} </button>
          </div>
        </div>
      </div>
    )
  }
}

共有1个答案

洪黎昕
2023-03-14

1.我所做的是否被认为是反模式?-也许,是的

问题是子组件的构造函数只在多个呈现中运行一次。如果在子组件中使用setstate()来重新呈现,构造函数将不会再次运行,因此道具和状态不同步,这就是本文提到的“真理的多源”问题。

如果重新呈现父组件(通过状态更改、道具更改或this.forceUpdate()),子组件的构造函数将不会重新执行。也就是说,React这样做是为了在内部提高性能,您可以使用console.log()来调查组件的生命周期。

<Todo todo={todo} key={i} onChangeCompletionCallback={() => {
    let clonedState = Object.assign({}, this.state);
    clonedState.todos[i].completed = !clonedState.todos[i].completed;
    this.setState(clonedState);
}}/>    
changeCompletion = () => {
    this.props.onChangeCompletionCallback();
}

让我们首先澄清render术语。React中有两种呈现:

  • 真实DOM呈现:慢
  • 虚拟DOM呈现:(设计为)快速

现在,如果您真正的DOM呈现200个todos,这肯定是不好的。但是如果您虚拟DOM呈现200个todos,这取决于情况。但大多数情况下,它会很快。

    null

因此,我认为在这种情况下,手动配置ShouldComponentUpdate(...)html" target="_blank">生命周期方法不会有太大帮助。看起来您保存了199个虚拟DOM呈现,但实际上您是在浪费精力。

 类似资料:
  • 本文向大家介绍Redux怎样设置初始状态?相关面试题,主要包含被问及Redux怎样设置初始状态?时的应答技巧和注意事项,需要的朋友参考一下 它必须是createStore的第二个参数: const rootReducer = combineReducers({ todos: todos, visibilityFilter: visibilityFilter }); const initialSta

  • 我正在使用React-useState创建状态为的对象。在成功调用API后,将更新为数据对象。 我有一个表单可以更改此状态,但我还有一个取消按钮。单击“取消”时,如何将此状态恢复为其初始值(API调用后)? 我应该创建另一个状态变量和存储初始状态在那里,然后更新我的状态基于?

  • 我有一个es6 react组件,我希望状态的初始值依赖于传递的道具的初始值,但它的值总是false: 我想这可能与state/setstate是异步的和旧的有关,但我不知道为什么。

  • 我有一个受控输入,它接受名为的道具。该对象由其父组件传递给它,并在其中用观察者1异步初始化。 在父组件中: 我想用填充受控输入的初始状态。类似下面的内容,这不应该是反模式,因为状态只依赖于构造上的prop。 当我刷新受控输入时,出现以下问题: 的值为,因为观察者尚未触发。组件被构造并将分配给. 观察者激发,为用户分配一个复杂的对象,React重新呈现组件。这不会更改组件的状态,仍然是。 我被困在如

  • 当安装完成并首次启动 Navicat Monitor 时,浏览器会弹出并打开你的 Navicat Monitor 的网址“http://<your_ip_address>:<port_number>”。你需要在欢迎页面完成 Navicat Monitor 的基本配置。 【注意】<your_host_address> 是安装了 Navicat Monitor 的系统的主机名,以及 <port_num