Reactjs、父组件、状态和道具

Posted

技术标签:

【中文标题】Reactjs、父组件、状态和道具【英文标题】:Reactjs, parent component, state and props 【发布时间】:2015-12-02 02:53:54 【问题描述】:

我实际上正在学习 reactjs,而且我实际上正在开发一个小 TODO 列表,包裹在一个名为 TODO 的“父组件”中。

在这个父组件内部,我想从相关存储中获取 TODO 的当前状态,然后将此状态作为属性传递给子组件。

问题是我不知道在哪里初始化我的父状态值。

事实上,我使用的是 ES6 语法,所以我没有 getInitialState() 函数。文档中写到我应该使用组件构造函数来初始化这些状态值。

事实是,如果我想在构造函数内部初始化状态,this.context(Fluxible Context)实际上是未定义的。

我决定将初始化移动到componentDidMount内部,但这似乎是一种反模式,我需要另一种解决方案。你能帮帮我吗?

这是我的实际代码:

import React from 'react';
import TodoTable from './TodoTable';
import ListStore from '../stores/ListStore';

class Todo extends React.Component 

  constructor(props)
    super(props);
    this.state = listItem:[];
    this._onStoreChange = this._onStoreChange.bind(this);
  

  static contextTypes = 
      executeAction: React.PropTypes.func.isRequired,
      getStore: React.PropTypes.func.isRequired
  ;

  componentDidMount() 
      this.setState(this.getStoreState()); // this is what I need to move inside of the constructor
      this.context.getStore(ListStore).addChangeListener(this._onStoreChange);
  

  componentWillUnmount() 
      this.context.getStore(ListStore).removeChangeListener(this._onStoreChange);
  

  _onStoreChange () 
   this.setState(this.getStoreState());
 

  getStoreState() 
      return 
          listItem: this.context.getStore(ListStore).getItems() // gives undefined
      
  

  add(e)
    this.context.executeAction(function (actionContext, payload, done) 
        actionContext.dispatch('ADD_ITEM', name:'toto', key:new Date().getTime());
    );
  


  render() 
    return (
      <div>
        <button className='waves-effect waves-light btn' onClick=this.add.bind(this)>Add</button>
        <TodoTable listItems=this.state.listItem></TodoTable>
      </div>
    );
  



export default Todo;

【问题讨论】:

我很好奇,您从哪里了解到在componentDidMount 方法中获取或设置state 是一种反模式 @TahirAhmed,这里:facebook.github.io/react/tips/… hmm 但在那篇文章中提到componentDidMount 的地方是什么?我的意思是我在我的项目中所做的几乎就是您正在做的,即在 componentDidMount 函数中使用 this.setState(...) 直到现在,我认为使用它就可以了。我现在很好奇其他人对此有何看法,因为我个人认为这没有任何问题。 【参考方案1】:

作为 Fluxible 用户,您应该受益于Fluxible addons:

connectToStores。

以下示例将监听 FooStore 和 BarStore 的变化,并在实例化时将 foo 和 bar 作为 props 传递给组件。

class Component extends React.Component 
    render() 
        return (
            <ul>
                <li>this.props.foo</li>
                <li>this.props.bar</li>
            </ul>
        );
    


Component = connectToStores(Component, [FooStore, BarStore], (context, props) => (
    foo: context.getStore(FooStore).getFoo(),
    bar: context.getStore(BarStore).getBar()
));

export default Component;

查看fluxible example 了解更多详情。代码摘录:

var connectToStores = require('fluxible-addons-react/connectToStores');
var TodoStore = require('../stores/TodoStore');
...

TodoApp = connectToStores(TodoApp, [TodoStore], function (context, props) 
    return 
        items: context.getStore(TodoStore).getAll()
    ;
);

因此你不需要调用 setState,所有的 store 数据都会在组件的 props 中。

【讨论】:

我想知道是否有可能将 Fluxible 从我们的反应组件中分离出来?你认为创建 reactjs 组件,导出它们,然后在另一个文件中导入时,我们在另一个文件中装饰它是个好主意吗?所以我们的 reactjs 组件可以很容易地导出,装饰只在fluxible项目内部 阅读这篇文章medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0。你应该让转储组件对fluxible一无所知(它们只使用props和自己的状态操作),只有***智能组件才会有一些逻辑来与fluxible store集成 所以我的解决方案似乎是一件好事,即使对于父组件不是? 只有当您打算在其他可能使用不同通量库的项目中重用根组件时,它才会证明成本是合理的。恕我直言,我不推荐,它会创建很多样板代码

以上是关于Reactjs、父组件、状态和道具的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS 从子组件修改父状态

通过 Parent 传递的 prop 获取子组件的当前状态 - Reactjs

键在 ReactJs 的子组件中不能作为道具使用

如何将子函数的参数传递给父 reactjs

reactjs 渲染状态或道具

如何从 Reactjs 中的 useEffect 挂钩访问道具