Назначение props для состояния и использование их из него - это анти-шаблон React (вы можете прочитать об этом здесь ).
Когда сценарий, которого вы пытаетесь достичь, требует что рекомендуемый способ - создать полностью управляемый компонент или, в данном случае, частично управляемый компонент, в котором не только rows
используются из свойств, но и любое преобразование на них также выполняется через свойства (в данном случае , сортировка).
Приведенный ниже фрагмент демонстрирует упрощенную версию рассматриваемой проблемы. Мы создаем компонент Parent
, который хранит rows
в своем состоянии, а также предоставляет метод, выполняющий сортировку. Затем он отображает полностью управляемый компонент Child
, которому не нужно иметь собственное состояние, и вместо этого получает строки, а также свою функцию сортировщика в качестве свойств.
Метод sortRows
показывает, как использовать setState
с обратным вызовом, который предлагает преимущество получения более согласованных результатов для состояния по сравнению с предоставлением вместо этого объекта состояния.
class Child extends React.PureComponent {
render() {
const { rows, sortRows } = this.props;
return (
<div>
<ul>{ rows.map((row, i) => (<li key={ i }>{ row }</li>)) }</ul>
<button onClick={ () => { sortRows(true) }}>Sort Ascending</button>
<button onClick={ () => { sortRows(false) }}>Sort Descending</button>
</div>
);
}
}
class Parent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
rows: ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter']
};
}
sortRows = (isSortAscending) => {
this.setState((prevState) => ({
rows: prevState.rows.slice().sort((a, b) => {
if (a < b) return -(isSortAscending ? 1 : -1);
if (a > b) return (isSortAscending ? 1 : -1);
return 0;
})
}));
}
render() {
return <Child rows={ this.state.rows } sortRows={ this.sortRows } />;
}
}
ReactDOM.render(<Parent />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>