Как передать значение фильтра как часть состояния и вернуть его как свойства, тем самым отфильтровав определенные элементы? - PullRequest
0 голосов
/ 27 мая 2020

На данный момент у меня есть список из 40 или около того пунктов меню, которые относятся к продуктовым магазинам, и у меня есть только возможность отображать все 40 магазинов одновременно. Я пытаюсь реализовать фильтр с помощью раскрывающегося меню, в котором вы выбираете имя магазина и отображаете только магазины с этим именем. Вот мой код для фильтра в файле под названием 'MenuComponent. js':

class FilterForm extends Component {
  constructor(props) {
    super(props);

    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(values) {
    console.log(values.filter);
  }

  render() {
    return(
      <LocalForm onSubmit={(values) => this.handleSubmit(values)}>
        <Control.select model=".filter" id="filter" name="filter" className="form-control">
          <option value="Safeway">Safeway</option>
          <option value="Whole Foods">Whole Foods</option>
          <option value="Luckys">Luckys</option>
          <option value="Sprouts">Sprouts</option>
        </Control.select>
        <Row className="form-group">
            <Col md={{size: 10, offset: 2}}>
                <Button type="submit" color="primary">
                    Filter
                </Button>
            </Col>
        </Row>
      </LocalForm>
    );
  };
}

Как часть этого файла у меня есть фактический компонент меню как таковой, также расположенный в 'MenuComponent. js ':

const Menu = (props) => {
    const menu = props.dishes.dishes.map((dish) => {
      return (
        <div key={dish.id} className="col-12 col-md-5 m-1">
            <RenderMenuItem dish={dish} comments={props.comments.comments.filter((comments) => comments.dishId === dish.id)} />
        </div>
      );
  });

  if (props.dishes.isLoading) {
    return(
      <div className="container">
        <div className="row">
          <Loading />
        </div>
      </div>
    );
  }
  else if (props.dishes.errMess) {
    return(
      <div className="container">
        <div className="row">
          <h4>{props.dishes.errMess}</h4>
        </div>
      </div>
    );
  }
  else
    return (
      <div className="container">
        <div className="row">
          <div className="col-12">
            <h3>STORES</h3>
            <FilterForm />
            <hr />
          </div>
        </div>
        <div className="row">
          {menu}
        </div>
      </div>
    );
}

export default Menu;

Я получаю правильное значение для values.filter. Мой вопрос в том, как передать этот файл values.filter и повторно отобразить элемент меню, чтобы я отображал только те элементы, где di sh .name === values.filter.

Родительский компонент находится в файле с именем MainComponent. js и выглядит следующим образом:

return (
        <div id="MainDiv">
            <Header />
                <TransitionGroup>
                    <CSSTransition key={this.props.location.key} classNames="page" timeout={300}>
                        <Switch>
                            <Route path="/home" component={HomePage} />
                            <Route exact path="/aboutus" component={AboutPage} />
                            <Route exact path="/menu" component={() => <Menu dishes={this.props.dishes} comments={this.props.comments} />} />
                            <Route path="/menu/:dishId" component={DishWithId} />
                            <Route exact path="/contactus" component={() => <Contact resetFeedbackForm={this.props.resetFeedbackForm}
                                    postFeedback={this.props.postFeedback} />} />
                            <Redirect to="/home" />
                        </Switch>
                    </CSSTransition>
                </TransitionGroup>
          <Footer />
        </div>
    );

Здесь я отображаю состояние и отправку на реквизиты:

const mapStateToProps = state => {
    return {
        dishes: state.dishes,
        comments: state.comments,
        promotions: state.promotions,
        leaders: state.leaders
    }
}

const mapDispatchToProps = (dispatch) => ({
    postComment: (dishId, rating, author, comment, masks, carts, sanitizer, monitor, oneway, register, card, numcust, gloves, curb, delivery) => dispatch(postComment(dishId, rating, author, comment, masks, carts, sanitizer, monitor, oneway, register, card, numcust, gloves, curb, delivery)),
    fetchDishes: () => {dispatch(fetchDishes())},
    resetFeedbackForm: () => { dispatch(actions.reset('feedback'))},
    fetchComments: () => {dispatch(fetchComments())},
    fetchPromos: () => {dispatch(fetchPromos())},
    fetchLeaders: () => {dispatch(fetchLeaders())},
    postFeedback: (firstname, lastname, telnum, email, agree, contactType, message) => dispatch(postFeedback(firstname, lastname, telnum, email, agree, contactType, message))
});

1 Ответ

0 голосов
/ 27 мая 2020

Вы можете передать функцию из Menu, которая будет использоваться в FilterForm для установки переменной состояния в Menu. Когда FilterForm обновляет переменную состояния в меню, меню будет повторно отображено с новым фильтром.

Поскольку Menu является функциональным компонентом, вы можете использовать ловушку useState.

const Menu = (props) => {
  const [filter, setFilter] = useState(null);
  ...
  // then pass the function to FilterForm
  <h3>STORES</h3>
    <FilterForm setFilter={setFilter} />
  <hr />

Добавить setFilter в FilterForm onSubmit

handleSubmit(values) {
  console.log(values.filter);
  this.props.setFilter(values.filter); // calls Menu's setFilter
}

Теперь у нас есть это значение. Меню

const Menu = (props) => {
  const [filter, setFilter] = useState(null);

  let dishes = props.dishes.dishes;
  if(filter !== null){
    // not sure if you call it storeName or something else, but filter the list
    dishes = dishes.filter((dish) => dish.storeName === filter);
  }

  // and then do map with the filtered list
  const menu = dishes.map((dish) => {
    return (
      <div key={dish.id} className="col-12 col-md-5 m-1">
          <RenderMenuItem dish={dish} comments={props.comments.comments.filter((comments) => comments.dishId === dish.id)} />
      </div>
    );
  });
  ...

Надеюсь, это поможет!

...