Reactjs变量在使用效果后返回undefined



我对Reactjs非常陌生,我正在努力检索一些数据以显示它,一切都得到显示,然而,当我过滤时出现"无法读取未定义的属性'过滤器'"的错误,经过调试,我发现dataList在搜索栏输入任何东西时返回未定义。谢谢你的帮助。

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;

您将有状态data变量与单独的非状态本地dataList变量混合在一起。dataList只被分配到axios.get内部,所以它在随后的渲染中没有定义;setData(dataList)将其放入有状态的data中,但dataList在随后的渲染中仍然未定义。

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

你可能也不想在用户输入内容时丢弃现有的数据——相反,找出在呈现时应该显示哪些项;修改filterData,使其逻辑只在返回JSX时执行。

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) => {

你的searchText也应该是text,而不是一个数组:this

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

应该

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

首先,您不需要维护一个额外的非状态变量dataList,因为本地状态data可以满足此目的。

API调用码:你应该在满足null检查后直接存储来自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]);

最新更新