Reactjs 变量在 useEffect 后返回 undefined

时间:2021-01-17 16:32:31

标签: javascript reactjs typescript

我对 Reactjs 很陌生,我正在检索一些数据以显示它,但是,所有内容都会显示出来,当我过滤时出现错误“无法读取未定义的属性‘过滤器’”,之后调试我发现在搜索栏中键入任何内容时 dataList 返回 undefined 。 感谢您的帮助。

function App() {

  var dataList;

useEffect(() => {
// http get request
const headers = {
  'Content-Type': 'application/json',
  'Authorization': '***********************',
  'UserAddressId': ****,
  'StoreId': *
}

axios.get('https://app.markitworld.com/api/v2/user/products', {
  headers: headers
})
  .then((response) => {
    dataList = response.data.data.products
    setData(dataList)
  })
  .catch((error) => {
    console.log(error)
  })
}, []);

const [searchText, setSearchText] = useState([]);
const [data, setData] = useState(dataList);

// exclude column list from filter
const excludeColumns = ["id"];

// handle change event of search input
const handleChange = value => {
setSearchText(value);
filterData(value);
};

// filter records by search text
const filterData = (value) => {
console.log("dataList", dataList)
const lowercasedValue = value.toLowerCase().trim();
if (lowercasedValue === "") setData(dataList);
else {
  const filteredData = dataList.filter(item => {
    return Object.keys(item).some(key =>
      excludeColumns.includes(key) ? false : 
      item[key].toString().toLowerCase().includes(lowercasedValue)
    );
  });
  setData(filteredData);
}
}

return (
<div className="App">
  Search: <input
    style={{ marginLeft: 5 }}
    type="text"
    placeholder="Type to search..."
    value={searchText}
    onChange={e => handleChange(e.target.value)}
  />
  <div className="box-container">
    {data && data.length > 0 ? data.map((d, i) => {
      return <div key={i} className="box">
        <b>Title: </b>{d.title}<br />
        <b>Brand Name: </b>{d.brand_name}<br />
        <b>Price: </b>{d.price}<br />
        <b>Status: </b>{d.status}<br />
      </div>
    }) : "Loading..."}
    <div className="clearboth"></div>
    {data && data.length === 0 && <span>No records found to display!</span>}
  </div>
  </div>
  );
  }

export default App;

2 个答案:

答案 0 :(得分:1)

您将有状态的 import sys; !{sys.executable} -m pip install jsonlines 变量与单独的无状态的本地 data 变量混在一起。 dataList 只被分配到 dataList 内部,所以它没有在后续渲染中定义; axios.get 将其放入有状态的 setData(dataList),但后续渲染中的 data 仍未定义。

为了使事情更容易理解,请完全删除 dataList 变量,而只使用有状态的 dataList

当用户输入内容时,您可能也不希望丢弃现有数据 - 相反,要弄清楚在渲染时应该显示哪些项目;重新设计 data,使其逻辑仅在返回 JSX 时执行。

filterData

改变

const [searchText, setSearchText] = useState([]);
const [data, setData] = useState([]);
useEffect(() => {
    // http get request
    const headers = {
        'Content-Type': 'application/json',
        'Authorization': '***********************',
        'UserAddressId': ****,
        'StoreId': *
    }

    axios.get('https://app.markitworld.com/api/v2/user/products', {
        headers: headers
    })
        .then((response) => {
            setData(response.data.data.products);
        })
        .catch((error) => {
            console.log(error)
        })
}, []);

// handle change event of search input
const handleChange = value => {
    setSearchText(value);
};

// filter records by search text
const filterData = () => {
    const lowercasedValue = searchText.toLowerCase().trim();
    return lowercasedValue === ""
        ? data
        : data.filter(
            item => Object.keys(item).some(
                key => excludeColumns.includes(key) ? false :
                    item[key].toString().toLowerCase().includes(lowercasedValue)
            )
        );
}

{data && data.length > 0 ? data.map((d, i) => {

您的 {filterData().map((d, i) => { 也应该是 text,而不是数组:this

searchText

应该

const [searchText, setSearchText] = useState([]);

答案 1 :(得分:0)

首先,您不需要维护额外的非状态变量 dataList,因为本地状态 data 就可以达到目的。

API 调用代码:

您应该在满足空检查后直接存储来自 API 的响应。

useEffect(() => {
  const headers = {
    // key value pairs go here
  };

  // http request
  axios.get(endPoint, {
    headers,
  })
    .then((response) => {
      // set data directly null checks
      setData(response.data.data.products);
    })
    .catch((error) => {
      console.log(error);
    });
}, []);

过滤代码

使用 useCallback 钩子会返回回调的记忆版本,除非 data 的值发生变化。

const filterData = useCallback((value) => {
  console.log('data', data);
  // rest of code
}, [data]);