如何将整个数组添加到 useState 变量



我正在尝试添加一个完整的数组来使用状态变量

import React, { Fragment, useState, useEffect } from 'react';
import { Form, Button, Popover, OverlayTrigger } from 'react-bootstrap';
const Filter = props => {
  const [formData, setFormData] = useState({
    filter: ''
  });
  const [items, setItems] = useState([]);
  const [retrievedItems, setRetrievedItems] = useState([]);
  const addToFilter = newFilter => {
    let retrievedFilter = ["da vinci","paris", "london"];
    console.log(retrievedFilter);
    if (retrievedFilter.length > 0) {
      setRetrievedItems([...retrievedItems, retrievedFilter]);
      retrievedFilter = 0;
      setRetrievedItems([...retrievedItems, newFilter]);
    } else {
      setItems([...items, newFilter]);
    }
    console.log('items are: ', items);
    console.log('retrieve filter', props.retrievedFilter);
    console.log('retrieved items: ', retrievedItems);
  };
  useEffect(() => {
    console.log('useEffect ', retrievedItems);
  }, [retrievedItems]);
  const deleteFilter = index => {
    // props.retrievedFilter.splice(index, 1);
    items.splice(index, 1);
    setItems([...items]);
    // setItems([...props.retrievedFilter, ...items]);
    console.log(items);
  };
  const { filter } = formData;
  const onChange = e => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };
  const onSubmit = e => {
    e.preventDefault();
    addToFilter(filter);
    // Passing filter data up (i.e: to components that use <Filter />)
    props.filterData(filter);
    //Close the Popover
    document.body.click();
  };
  const popover = (
    <Popover id="popover-basic">
      <Form>
        <Form.Group controlId="formGroupEmail">
          <Form.Label>Add New Filter</Form.Label>
          <Form.Control
            type="text"
            placeholder="New Filter"
            name="filter"
            onChange={e => onChange(e)}
          />
        </Form.Group>
        <Button variant="dark" type="submit" onClick={e => onSubmit(e)}>
          Add
        </Button>
      </Form>
    </Popover>
  );
  return (
    <Fragment>
      <label>
        <p className="filter-title">{props.title}</p>
      </label>
      <div className={props.className ? props.className : 'filter'}>
        {!props.retrievedFilter
          ? items.map((item, index) => {
              return (
                <div className="filter-text" key={index}>
                  {item}
                  <Button
                    className="filter-button"
                    size="sm"
                    onClick={() => deleteFilter(index)}
                  >
                    X
                  </Button>
                </div>
              );
            })
          : props.retrievedFilter.map((item, index) => {
              return (
                <div className="filter-text" key={index}>
                  {item}
                  <Button
                    className="filter-button"
                    size="sm"
                    onClick={() => deleteFilter(index)}
                  >
                    X
                  </Button>
                </div>
              );
            })}
        <OverlayTrigger
          trigger="click"
          placement="right"
          rootClose
          overlay={popover}
        >
          <p className="text-field">Type new one</p>
        </OverlayTrigger>
      </div>
    </Fragment>
  );
};
export default Filter;

但是检索到的项目在控制台中显示为空数组。

任何帮助将不胜感激。

>setState是异步的。您必须在效果钩子中控制台.log数组作为参数。

useEffect(() => console.log(retrieved_items), [ retrievedItems ])

第二个参数可确保效果在传递给它的值发生变化时触发。

根据我的评论,这里有一个我认为可以满足您想要的代码片段。

我无法让它在 SO 中运行,但这里有一个代码笔:https://codepen.io/anon/pen/PrYYmz?editors=1010(在添加项目时观看 chrome 控制台(

import React, {
  Fragment,
  useState,
  useEffect
} from 'react';
const Filter = props => {
  const [formData, setFormData] = useState({filter: ''});
  const [items, setItems] = useState([]);
  const [retrievedItems, setRetrievedItems] = useState([]);
  const addToFilter = newFilter => {
    let retrievedFilter = ["da vinci", "paris", "london"];
    console.log('add', retrievedFilter);
    if (retrievedFilter.length > 0) {
      setRetrievedItems([...retrievedItems, retrievedFilter]);
      retrievedFilter = 0;
      setRetrievedItems([...retrievedItems, newFilter]);
    } else {
      setItems([...items, newFilter]);
    }
    console.log('items are: ', items);
    console.log('retrieve filter', props.retrievedFilter);
    console.log('retrieved items: ', retrievedItems);
  };
  useEffect(() => {
    console.log('useEffect ', retrievedItems);
  }, [retrievedItems]);
  const deleteFilter = index => {
    // props.retrievedFilter.splice(index, 1);
    items.splice(index, 1);
    setItems([...items]);
    // setItems([...props.retrievedFilter, ...items]);
    console.log(items);
  };
  const {filter} = formData;
  const onChange = e => {
    setFormData({ ...formData,
      [e.target.name]: e.target.value
    });
  };
  const onSubmit = e => {
    e.preventDefault();
    addToFilter(filter);
    // Passing filter data up (i.e: to components that use <Filter />)
    //props.filterData(filter);
    //Close the Popover
    document.body.click();
  };
  return (
  <Fragment >
    <label >
    <p className = "filter-title" > {
      props.title
    } </p> </label> <
    div className = {
      props.className ? props.className : 'filter'
    } > {!props.retrievedFilter ?
      items.map((item, index) => {
        return ( <
          div className = "filter-text"
          key = {index} > {item} <button className = "filter-button" size = "sm" onClick = {() => deleteFilter(index)}>X</button></div>
        );
      }) :
        props.retrievedFilter.map((item, index) => {
        return ( <div className = "filter-text" key = {index} > {item} <button className = "filter-button" size = "sm" onClick = {() => deleteFilter(index)} >X</button></div>);})} <input type = "text" placeholder = "New Filter" name = "filter" onChange = {e => onChange(e) }/> 
        <button variant = "dark" type = "submit" onClick = {e => onSubmit(e)} >Add</button>
        </div>
    </Fragment>
  );
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

相关内容

  • 没有找到相关文章