С React DOCS :
Помните: React - это все о односторонний поток данных вниз поиерархия компонентов. Может быть не сразу понятно, какой компонент должен принадлежать какому состоянию.Это часто самая сложная часть для понимания новичками, поэтому следуйте этим шагам, чтобы понять это:
Односторонний поток данных React предназначен для сверху вниз ,родитель-ребенок.То, как вы предлагаете, будет братья и сестры, которые будут из стороны в сторону вместо сверху вниз .Это анти-шаблон.
Вы можете настроить иерархию компонентов следующим образом:
Посмотрите, что вам подходит.
function App() {
function doSomethingApp(formValue) {
console.log('Do something from App!');
console.log('Form value is: ' + formValue);
}
return(
<React.Fragment>
<Table/>
<Form
doSomethingApp={doSomethingApp}
/>
</React.Fragment>
);
}
function Table(props) {
function doSomethingTable(formValue) {
console.log('Do something from Table!');
console.log('Form value is: ' + formValue);
}
return(
<div>I am Table</div>
);
}
function Form(props) {
const [value,setValue] = React.useState('');
return(
<React.Fragment>
<div>I am Form</div>
<input type='text' value={value} onChange={()=>setValue(event.target.value)}/>
<div>
<button onClick={()=>props.doSomethingApp(value)}>Do something from App</button>
</div>
</React.Fragment>
);
}
ReactDOM.render(<App/>,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
SNIPPET: ВНИМАНИЕ, ЭТО АНТИ-УЗОР
Хотя я бы не рекомендовал этосовсем.Это рабочий пример запрошенного вами анти-паттерна.
У Sibling1 есть useEffect
, который обновляет состояние общего родителя App
с помощью метода showData
.Всякий раз, когда showData
изменяется, эффект запускается снова и обновляется.showData
является запомненным обратным вызовом.Вы можете добавить массив зависимостей, чтобы обновлять этот запомненный обратный вызов при изменении какой-либо другой переменной.
Источник: Справочник по API хуков
function App() {
const [sibling1Method,setSibling1Method] = React.useState({method: null});
return(
<React.Fragment>
<Sibling1
setSibling1Method={setSibling1Method}
/>
<Sibling2
sibling1Method={sibling1Method}
/>
</React.Fragment>
);
}
function Sibling1(props) {
const showData = React.useCallback((formValue) => {
console.log('A click from Sibling2 is triggering a Sibling1 Method');
},[]);
React.useEffect(()=>{
props.setSibling1Method({method: showData});
},[showData]);
return(
<div>Sibling 1 </div>
);
}
function Sibling2(props) {
return(
<React.Fragment>
<span>Sibling 2 </span>
<button onClick={()=>props.sibling1Method.method()}>Click</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>