防止在基础数据更改时更改下拉选项
Prevent change of dropdown options when underlying data changes
使用以下代码:
<!DOCTYPE html>
<html>
<body>
<head>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<style>
</style>
</head>
<body>
<div id="root">
</body>
<script type="text/babel">
const api = {
data: [
{
id: 1, party: 'Zuckerberg', news: [
{id: 1, headline: 'Zuckerberg news1'},
{id: 2, headline: 'Zuckerberg news2'},
]
},
{
id: 2, party: 'Musk', news: [
{id: 1, headline: 'Musk news1'},
{id: 2, headline: 'Musk news2'},
]
},
]
}
const App = () => {
const [data, setData] = React.useState([])
React.useEffect(() => setData(api.data), [])
const handleSelectChange = (e) => {
const name = e.target.value
setData(prev => prev.filter(datum => datum.party === name))
}
return (
<div>
<select
onChange={handleSelectChange}>
{data.map(datum => <option key={datum.id}>{datum.party}</option>)}
</select>
{data.map(
datum =>
datum.news.map(newsItem =>
<div key={newsItem.id}>{newsItem.headline}</div>
)
)}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
</script>
</html>
如何防止在下拉列表更改时减少下拉选项,最好是在不更改 api.data
结构的情况下 ?
我基本上只需要在 api.data
returns 新数据时刷新此下拉列表。
是否可能同时保持单一状态(data
)?
我已经在下面修改了你的代码。
要点:
- 删除了 useEffect - API 是静态的,因此不需要 re-allocated
- useState 仅监视过滤器(API 数据的过滤仅在状态更改时发生,因此不需要存储它 - 但如果需要,您可以使用 Memo 并使其依赖于数据)
- 选项源自api.data
<!DOCTYPE html>
<html>
<body>
<head>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<style>
</style>
</head>
<body>
<div id="root">
</body>
<script type="text/babel">
const api = {
data: [
{
id: 1, party: 'Zuckerberg', news: [
{id: 1, headline: 'Zuckerberg news1'},
{id: 2, headline: 'Zuckerberg news2'},
]
},
{
id: 2, party: 'Musk', news: [
{id: 1, headline: 'Musk news1'},
{id: 2, headline: 'Musk news2'},
]
},
]
}
const App = () => {
const [data, setData] = React.useState(api.data.length?api.data[0].party:undefined)
const handleSelectChange = (e) => {
setData(e.target.value)
}
return (
<div>
<select
onChange={handleSelectChange}>
{api.data.map(datum => <option key={datum.id}>{datum.party}</option>)}
</select>
{api.data.filter(datum=>datum.party===data).map(
datum =>
datum.news.map(newsItem =>
<div key={newsItem.id}>{newsItem.headline}</div>
)
)}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
</script>
</html>
我想不出不使用另一个状态变量的方法。为什么只想要一个变量?
您可以像 Qubaish 所说的那样使用对象状态变量,但这比仅使用第二个状态变量更难维护。
如果您可以使用两个状态变量,请使用以下方法:
const App = () => {
const [data, setData] = React.useState([]);
const [options, setOptions] = useState([]);
React.useEffect(() => {
setData(api.data);
setOptions(api.data);
}, []);
const handleSelectChange = (e) => {
let name = e.target.value;
setData(options.filter((datum) => datum.party === name));
};
return (
<div>
<select onChange={handleSelectChange}>
{options.map((datum) => (
<option key={datum.id}>{datum.party}</option>
))}
</select>
{data.map((datum) =>
datum.news.map((newsItem) => (
<div key={newsItem.id}>{newsItem.headline}</div>
))
)}
</div>
);
};
它只是将options状态下的潜在options复制一份,然后将要显示的数据存储在“data”中。
处理这种情况的一种方法是将状态定义为我在评论中提到的对象。这可能对你有帮助。它对我有用。
const MyComponent = () => {
const [data, setData] = React.useState({})
React.useEffect(() => setData({dropdownValues: api.data, filteredValues: api.data}), [])
const handleSelectChange = (e) => {
const name = e.target.value
const filteredValues = data.dropdownValues.filter(datum => datum.party === name);
setData({...data, filteredValues})
}
return (
<div>
<select
onChange={handleSelectChange}>
{data.dropdownValues && data.dropdownValues.map(datum => <option key={datum.id}>{datum.party}</option>)}
</select>
{data.filteredValues && data.filteredValues.map(
datum =>
datum.news.map(newsItem =>
<div key={newsItem.id}>{newsItem.headline}</div>
)
)}
</div>
)
}
使用以下代码:
<!DOCTYPE html>
<html>
<body>
<head>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<style>
</style>
</head>
<body>
<div id="root">
</body>
<script type="text/babel">
const api = {
data: [
{
id: 1, party: 'Zuckerberg', news: [
{id: 1, headline: 'Zuckerberg news1'},
{id: 2, headline: 'Zuckerberg news2'},
]
},
{
id: 2, party: 'Musk', news: [
{id: 1, headline: 'Musk news1'},
{id: 2, headline: 'Musk news2'},
]
},
]
}
const App = () => {
const [data, setData] = React.useState([])
React.useEffect(() => setData(api.data), [])
const handleSelectChange = (e) => {
const name = e.target.value
setData(prev => prev.filter(datum => datum.party === name))
}
return (
<div>
<select
onChange={handleSelectChange}>
{data.map(datum => <option key={datum.id}>{datum.party}</option>)}
</select>
{data.map(
datum =>
datum.news.map(newsItem =>
<div key={newsItem.id}>{newsItem.headline}</div>
)
)}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
</script>
</html>
如何防止在下拉列表更改时减少下拉选项,最好是在不更改 api.data
结构的情况下 ?
我基本上只需要在 api.data
returns 新数据时刷新此下拉列表。
是否可能同时保持单一状态(data
)?
我已经在下面修改了你的代码。
要点:
- 删除了 useEffect - API 是静态的,因此不需要 re-allocated
- useState 仅监视过滤器(API 数据的过滤仅在状态更改时发生,因此不需要存储它 - 但如果需要,您可以使用 Memo 并使其依赖于数据)
- 选项源自api.data
<!DOCTYPE html>
<html>
<body>
<head>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<style>
</style>
</head>
<body>
<div id="root">
</body>
<script type="text/babel">
const api = {
data: [
{
id: 1, party: 'Zuckerberg', news: [
{id: 1, headline: 'Zuckerberg news1'},
{id: 2, headline: 'Zuckerberg news2'},
]
},
{
id: 2, party: 'Musk', news: [
{id: 1, headline: 'Musk news1'},
{id: 2, headline: 'Musk news2'},
]
},
]
}
const App = () => {
const [data, setData] = React.useState(api.data.length?api.data[0].party:undefined)
const handleSelectChange = (e) => {
setData(e.target.value)
}
return (
<div>
<select
onChange={handleSelectChange}>
{api.data.map(datum => <option key={datum.id}>{datum.party}</option>)}
</select>
{api.data.filter(datum=>datum.party===data).map(
datum =>
datum.news.map(newsItem =>
<div key={newsItem.id}>{newsItem.headline}</div>
)
)}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
</script>
</html>
我想不出不使用另一个状态变量的方法。为什么只想要一个变量?
您可以像 Qubaish 所说的那样使用对象状态变量,但这比仅使用第二个状态变量更难维护。
如果您可以使用两个状态变量,请使用以下方法:
const App = () => {
const [data, setData] = React.useState([]);
const [options, setOptions] = useState([]);
React.useEffect(() => {
setData(api.data);
setOptions(api.data);
}, []);
const handleSelectChange = (e) => {
let name = e.target.value;
setData(options.filter((datum) => datum.party === name));
};
return (
<div>
<select onChange={handleSelectChange}>
{options.map((datum) => (
<option key={datum.id}>{datum.party}</option>
))}
</select>
{data.map((datum) =>
datum.news.map((newsItem) => (
<div key={newsItem.id}>{newsItem.headline}</div>
))
)}
</div>
);
};
它只是将options状态下的潜在options复制一份,然后将要显示的数据存储在“data”中。
处理这种情况的一种方法是将状态定义为我在评论中提到的对象。这可能对你有帮助。它对我有用。
const MyComponent = () => {
const [data, setData] = React.useState({})
React.useEffect(() => setData({dropdownValues: api.data, filteredValues: api.data}), [])
const handleSelectChange = (e) => {
const name = e.target.value
const filteredValues = data.dropdownValues.filter(datum => datum.party === name);
setData({...data, filteredValues})
}
return (
<div>
<select
onChange={handleSelectChange}>
{data.dropdownValues && data.dropdownValues.map(datum => <option key={datum.id}>{datum.party}</option>)}
</select>
{data.filteredValues && data.filteredValues.map(
datum =>
datum.news.map(newsItem =>
<div key={newsItem.id}>{newsItem.headline}</div>
)
)}
</div>
)
}