【问题标题】:React - Passing State between siblings?React - 兄弟姐妹之间的传递状态?
【发布时间】:2017-04-23 01:09:08
【问题描述】:

对于 React 来说基本上是新手,我对如何在组件之间正确传递状态有点困惑。我已经发现了一个类似的问题React – the right way to pass form element state to sibling/parent elements? 但不知道您能否针对下面的代码给我一个具体的答案。

目前应用的结构包括:

  • 父组件 - App
  • 2 个孩子:SearchBarRecipesList

目标是对我的 Meteor 集合进行异步搜索,并仅显示与搜索词匹配的 recipes

现在,我只是展示我的 Meteor 收藏中的所有食谱。 我创建了一个名为SearchBar 的有状态组件,它将输入值保存为this.state.term。这个想法是将状态传递给RecipesList,但我不确定这是否是正确的做法。或者,我会让App 处理状态并将其传递给孩子。我相信这是一个很常见的场景,你是怎么做到的?

App

class App extends Component {

render( ) {
    return (
        <div>
            <Navbar/>
            <SearchBar/>
            <RecipesList/>
        </div>
    );
}
}

SearchBar

export default class SearchBar extends Component {

constructor( props ) {
    super( props );

    this.state = {
        term: ''
    };
}

onInputChange( term ) {
    this.setState({ term });
}

render( ) {
    return (
        <div className=" container-fluid search-bar">
            <input value={this.state.term} onChange={event => this.onInputChange(event.target.value.substr( 0, 50 ))}/>
            Value: {this.state.term}
        </div>
    );
}

}

RecipesList

const PER_CLICK = 5;

class RecipesList extends Component {

componentWillMount( ) {
    this.click = 1;
}

handleButtonClick( ) {
    Meteor.subscribe('recipes', PER_CLICK * ( this.click + 1 ));
    this.click++;
}

renderList( ) {
    return this.props.recipes.map(recipe => {
        return (
            <div key={recipe._id} className="thumbnail">
                <img src={recipe.image} alt="recipes snapshot"/>
                <div className="caption">
                    <h2 className="text-center">{recipe.recipeName}</h2>
                </div>
            </div>
        );
    });
}

render( ) {
    return (
        <ul className="list-group">
            {this.renderList( )}
            <div className="container-fluid">
                <button onClick={this.handleButtonClick.bind( this )} className="btn btn-default">More</button>
            </div>
        </ul>
    );
}
}

// Create Container and subscribe to `recipes` collection
export default createContainer( ( ) => {
Meteor.subscribe( 'recipes', PER_CLICK );
return {recipes: Recipes.find({ }).fetch( )};
}, RecipesList );

【问题讨论】:

标签: javascript reactjs meteor


【解决方案1】:

App

class App extends Component {
  constructor(props, ctx){
    super(props, ctx)

    this.state = {
      searchQuery: ''
    }

    this.searchInputChange = this.searchInputChange.bind(this)
  }

  searchInputChange(event) {
    this.setState({
      searchQuery: event.target.value.substr( 0, 50 )
    })
  }

  render( ) {
    const { searchQuery } = this.state
    return (
      <div>
        <Navbar/>
        <SearchBar onChange={this.searchInputChange} value={searchQuery}/>
        <RecipesList searchQuery={searchQuery}/>
      </div>
    )
  }
}

App 组件负责处理状态,然后将其作为 props 传递给子项,搜索项可通过 props.searchQuery 提供给 RecipesList

searchInputChange 处理程序作为道具传递给SearchBar

SearchBar

export default const SearchBar = ({value, onChange}) => (
  <div className=" container-fluid search-bar">
    <input value={value} onChange={onChange}/>
    Value: {value}
  </div>
)

由于SearchBar 将状态委托给父组件,我们可以使用无状态的反应组件,因为我们只需要来自道具的信息来呈现它。

一般来说,最好有一个logicalstatefulcontroller 组件来处理状态和逻辑,然后该组件将状态和方法传递给presentationalview 组件关注用户看到的和与之交互的内容。

【讨论】:

    【解决方案2】:

    在 App 组件中定义状态 term。 还要写handleInput函数,作为porps传给SearchBar组件

    handleInput(val) {
    this.setState({
        term: val,
    });
    }
    

    当在搜索栏中输入某些内容时(onKeyUp)添加侦听器句柄输入。

    同时创建&lt;RecipesList searchQuery={this.state.term}/&gt;

    现在在渲染函数 RecipesList 中过滤掉您想要从列表中显示的食谱

    【讨论】:

      猜你喜欢
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 2020-02-05
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2019-05-06
      相关资源
      最近更新 更多