首页 文章

反应 - 在兄弟姐妹之间传递状态?

提问于
浏览
4

基本上是React的新手,我对如何在组件之间正确传递状态感到困惑 . 我发现了一个类似的问题React – the right way to pass form element state to sibling/parent elements?但我想知道你是否可以给我一个特定的答案,代码如下 .

目前,该应用程序的结构包括:

  • 父组件 - App

  • 2个孩子: SearchBarRecipesList

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

现在,我'm just showing all the recipes in my Meteor collection. I' ve创建了一个名为 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 );

2 回答

  • 2

    将状态 term 定义到App组件中 . 还要编写handleInput函数并将其作为porps传递给SearchBar组件

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

    当输入搜索栏中的某些内容(onKeyUp)时,添加侦听器handleInput .

    同时创建 <RecipesList searchQuery={this.state.term}/>

    现在在渲染功能RecipesList过滤掉你想要从列表中显示的食谱

  • 0

    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.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 委托状态到父组件,我们可以使用无状态反应组件,因为我们只需要来自props的信息来呈现它 .

    通常,最好让 logicalstatefulcontroller 组件处理状态和逻辑,然后该组件将状态和方法传递给 presentationalview 组件,这些组件负责用户看到和交互的内容 .

相关问题