我正在尝试构建onChange搜索功能。在建议列表中,我的状态如下:
results: {
page: 1,
results: [
{value: 'popularity.desc', label: 'Popularity Descending'},
{value: 'popularity.asc', label: 'Popularity Ascending'},
{value: 'new value', label: 'new label'},
{value: 'vote_average.desc', label: 'Rating Descending'}
]
}
当用户选择{value: 'new value', label: 'new label'}
对象时。
如何将对象移至状态数组results
的第一个索引?
例如:选择对象之后。状态应该是这样的:
results: {
page: 1,
results: [
{value: 'new value', label: 'new label'},
{value: 'popularity.desc', label: 'Popularity Descending'},
{value: 'popularity.asc', label: 'Popularity Ascending'},
{value: 'vote_average.desc', label: 'Rating Descending'}
]
}
我的想法是使用传播运算符和过滤器,但我不知道如何实现。
选择项目方法:
onSuggestionSelected = (event, {suggestion, suggestionValue }) => {
console.log('Selected', suggestion); // {value: 'new value', label: 'new label'}
if (suggestion.media_type === 'movie') {
this.navigate('/search/movie', suggestionValue, suggestion);
} else if (suggestion.media_type === 'tv') {
this.navigate('/search/tv', suggestionValue, suggestion);
} else {
this.navigate('/search', suggestionValue, suggestion);
}
};
选择后,它将导航:
navigate = (pathname, queryValue, resultValue) => {
// ResultValue is that Object that I want to shift first.
this.props.history.push({
pathname,
search: `?query=${queryValue}`,
state: {results: this.state.data}});
};
答案 0 :(得分:2)
//filtered the remaining item
let remainValue = result.filter((obj, key) => obj.value != suggestion.value);
//merge here
let newResult = [suggestion, ...remainValue]; //it will contain reordered item
答案 1 :(得分:1)
您可以找到要放在数组中的result
的索引,然后将其放在数组的result
之前和之后的索引的前面。
示例
class App extends React.Component {
state = {
results: {
page: 1,
results: [
{ value: "popularity.desc", label: "Popularity Descending" },
{ value: "popularity.asc", label: "Popularity Ascending" },
{ value: "new value", label: "new label" },
{ value: "vote_average.desc", label: "Rating Descending" }
]
}
};
putResultFirst = result => {
this.setState(previousState => {
const { results } = previousState.results;
const resultIndex = results.indexOf(result);
return {
results: {
...results,
results: [
result,
...results.slice(0, resultIndex),
...results.slice(resultIndex + 1)
]
}
};
});
};
render() {
return (
<div>
{this.state.results.results.map(result => (
<div key={result.id} onClick={() => this.putResultFirst(result)}>
{result.value} {result.label}
</div>
))}
</div>
);
}
}
答案 2 :(得分:1)
首先,我们需要使用index
找到一个findIndex
,然后使用filter
当前状态来排除包含所选数据的对象。
我们最后要做的是使用扩展运算符...
将结果合并为一个数组。
示例:
const currentState = [
{value: 'popularity.desc', label: 'Popularity Descending'},
{value: 'popularity.asc', label: 'Popularity Ascending'},
{value: 'new value', label: 'new label'},
{value: 'vote_average.desc', label: 'Rating Descending'}
];
const selectedValue = {value: 'new value', label: 'new label'};
const onSelectionChange = (selected) => {
const selectedIndex = currentState.findIndex(({ value }) => value === selected.value);
const selectedItem = currentState[selectedIndex];
const stateExcludedItem = currentState.filter(({ value }) => value !== selected.value);
const newState = [ selectedItem, ...stateExcludedItem ]
// this.setState
return newState;
}
const result = onSelectionChange(selectedValue);
console.log(result);
答案 3 :(得分:0)
要将选定项移到第一位置,可以使用Array.filter方法将未选定项作为数组获取,并构建一个新的结果数组:
selectedItem = this.state.results.results[clickedIndex]
unselectedItems = this.state.results.results.filter((item, index) => clickedIndex !== index)
因为处于状态的“结果”是一个对象。要更新处于该状态的对象,您应该复制当前结果对象以创建一个新对象,以便更新状态。
results = {...this.state.results, results: [selectedItem, ...unselectedItems]}
您只想将所选项目移到结果数组的顶部,因此只需将所选项目的索引传输到事件处理程序,该处理程序将调用setState
方法。
示例代码:
class App extends React.Component {
state = {
results: {
page: 1,
results: [
{value: 'popularity.desc', label: 'Popularity Descending'},
{value: 'popularity.asc', label: 'Popularity Ascending'},
{value: 'new value', label: 'new label'},
{value: 'vote_average.desc', label: 'Rating Descending'}
]
}
};
handelClick = (clickedIndex) => {
if(clickedIndex === 0) {
return;
}
let selectedItem = this.state.results.results[clickedIndex],
unselectedItems = this.state.results.results.filter((item, index) => clickedIndex !== index),
results = {...this.state.results, results: [selectedItem, ...unselectedItems]};
this.setState({results})
};
render() {
return <ul>
{this.state.results.results.map((item, index) =>
<li key={item.label} onClick={this.handelClick.bind('', index)}>{item.label}</li>)
}
</ul>
}
}
const renderFilterList = () => {
ReactDOM.render(<App />, document.getElementById('react-app'));
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="react-app"></div>