Как передать данные к более "древнему" родительскому компоненту?
Мне нужно, чтобы данные от дочернего компонента Li доходили до родительского компонента 3-4 уровня -- Li -> Menu -> App
Вот мой код, пытался использовать onChange, но он работает только для форм
export default function App(){
const style = {
maxWidth: 1200 + 'px',
margin: '0 auto',
padding: '0 15px'
}
const handleClick = (value: any) => {
console.log(value);
}
return(
<div style = {style} >
<Menu test2 = {handleClick} />
</div>
)
}
function Menu(props: any){
const [click , setClick] = useState('')
const style = {
margin: 0,
padding: 0
}
const handleTest = () => {
props.test2(click);
}
const handleClick = (value: any) => {
setClick(value);
}
return (
<nav data-test = {handleTest}>
<ul style = {style}>
<Li test = {handleClick}>hi</Li>
</ul>
</nav>
)
}
function Li(props: any){
const style = {
listStyle: 'none',
fontSize: 24 + 'px'
}
const [click, setClick] = useState('');
const handleClick = () => {
props.test('pidoras')
setClick('hi');
}
return (
<li
style = {style}
onClick = {handleClick}>
{props.children} <br />
{click}
</li>
)
}
Ответы (1 шт):
Ниже пример, как можно пробрасывать функции из родительского компонента в дочерний любой вложенности.
По сути, надо просто передавать саму фукнцию в пропсы дочернего компонента.
Создадим родительский компонент, в котором будет состояние и рендер дочернего компонента. В дочерний компонент Second мы передаем фукнцию setVal в параметре click click={setVal}. Так же передадим значения для рендера(массив) renderData.
const App = () => {
const [val, setVal] = useState("");
const [renderData, setRenderData] = useState([
{ name: "one", value: 1 },
{ name: "two", value: 2 },
{ name: "three", value: 3 }
]);
return (
<div className="App">
<Second click={setVal} renderData={renderData} />
<hr />
{val}
</div>
);
};
В компоненте Second мы принимам параметры click и renderData. В компоненте первый рендер массива передаем "как есть" переменную click(в ней лежит функция из App) и сам элемент в компонент Line. Во второй рендр(для примера) передадим фукнцию modify, которая будет добавлять 10 к полученному значению.
const Second = ({ clickб renderData }) => {
const modify = (val) => {
click(val + 10);
};
return (
<>
Пробрасываем функцию как есть:
<br />
{lines.map((item) => (
<Line key={item.name} data={item} click={click} />
))}
<br />
Пробрасываем модифицированную функцию:
<br />
{lines.map((item) => (
<Line key={item.name} data={item} click={modify} />
))}
</>
);
};
Сам компонент Line принимает на вход data(Данные для отрисовки) и click(функция, которая будет установлена для события onClick()
const Line = ({ data, click }) => {
return <button onClick={() => click(data.value)}>{data.name}</button>;
};
Таким образом, мы протянули функцию через 2 компонента. При необходимости, ее можно и через 10 протянуть.
Работающий пример данного ответа в песочнице codesandbox