[英]Transferring data between React elements
试图弄清楚如何在兄弟组件之间传输数据。 想法是这样的:您需要确保只有一个子组件具有“活动” class(只能选择一个 div)。 这是代码: https://codepen.io/slava4ka/pen/rNBoJGp
import React, {useState, useEffect} from 'react';
import styleFromCss from './Garbage.module.css';
const ChildComponent = (props) => {
const [style, setStyle] = useState(`${styleFromCss.childComponent}`);
const [active, setActive] = useState(false)
const setActiveStyle = () => {
console.log("setActiveStyle");
if (!active) {
setStyle(`${styleFromCss.childComponent} ${styleFromCss.active}`)
setActive(true)
} else {
setStyle(`${styleFromCss.childComponent}`);
setActive(false)
}
};
//console.log(props);
console.log(`id ${props.id} style ${style}`);
return (
<div className={style} onClick={() => {
props.updateData(props.id, () => setActiveStyle())
}}>
<h3>{props.name}</h3>
</div>
)
};
const ParentComponent = (props) => {
const state = [{'id': 0, 'name': 'один'}, {'id': 1, 'name': 'два'}, {'id': 2, 'name': 'три'}];
const [clicked, setClicked] = useState(null);
const highlight = (id, makeChildActive) => {
//console.log("click! " + id);
setClicked(id);
makeChildActive();
};
return (
<div>
{state.map(entity => <ChildComponent updateData={highlight}
key={entity.id}
id={entity.id}
name={entity.name}
isActive={(entity.id ===
clicked) ? styleFromCss.active : null}
/>)}
</div>
)
};
export default ParentComponent;
styleFromCss.module.css:
.childComponent{
width: 200px;
height: 200px;
border: 1px solid black;
margin: 10px;
float: left;
text-align: center;
}
.active{
background-color: blueviolet;
}
我试图通过钩子而不是类来实现这一点。 结果,当您单击所选组件时,其类会发生变化,而其兄弟姐妹则不会发生任何事情。 据我了解,他们根本不重绘。 问题是如何修复它? 这种方法对于实现给定目标是否正确? 或者我的想法从根本上是错误的,我将不胜感激)))
您需要将 function 从处理父组件中 state 更改的父组件向下传递给子组件,以获取确定哪个 id 为“active”的 state。 然后将 activeId 作为道具传递给孩子。 在孩子中,将 id 与 activeId 进行比较,并相应地应用 class。
您不能使用Child的onClick方法将样式设置为单击一个Child时,其他Child不知道:((
相反,当您单击一个子级时,它会告诉父级它被单击(您已经使用 setClicked() 正确执行此操作),然后父级可以告诉每个子级它们是否处于活动状态(通过传递 IsActive 布尔值),并且每个Child 使用它的 props.isActive boolean 来设置它的样式:D
const ChildComponent = (props) => {
let style = 'childComponent'
if (props.isActive) style = style + ' active'
return (
<div className={style} onClick={() => {
props.updateData(props.id)
}}>
<h3>{props.name}</h3>
</div>
)
};
const ParentComponent = (props) => {
const state = [{'id': 0, 'name': 'один'}, {'id': 1, 'name': 'два'}, {'id': 2, 'name': 'три'}];
const [clicked, setClicked] = React.useState(null);
const highlight = (id) => {
setClicked(id);
};
return (
<div>
{state.map(entity =>
<ChildComponent updateData={highlight}
key={entity.id}
id={entity.id}
name={entity.name}
isActive={entity.id === clicked}
/>
)}
</div>
)
};
ReactDOM.render(
<ParentComponent/>,
document.getElementById('root')
);
正确,这是错误的思考方式。 如果您希望一次只选择一个孩子,则应在父项中保留“选择了哪个孩子”数据。 每个孩子也不应该管理自己突出显示的 state 版本; 相反,它应该是给每个孩子的道具(每个孩子都是纯 function。)试试这个:
const ChildComponent = props => {
return (
<div
className={'childComponent' + (props.isActive ? ' active' : '')}
onClick={() => props.setHighlighted(props.id)}
>
<h3>{props.name}</h3>
</div>
);
};
const ParentComponent = props => {
const state = [
{ id: 0, name: 'один' },
{ id: 1, name: 'два' },
{ id: 2, name: 'три' }
];
const [clicked, setClicked] = React.useState(null);
return (
<div>
{state.map(entity => (
<ChildComponent
setHighlighted={setClicked}
key={entity.id}
id={entity.id}
name={entity.name}
isActive={entity.id === clicked ? 'active' : null}
/>
))}
</div>
);
};
ReactDOM.render(<ParentComponent />, document.getElementById('root'));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.