我有一个表格组件(父组件),在表格的每一行中,还有另一个组件,基本上是一个图像按钮(子组件)。单击后,图像按钮将从其默认的三个垂直点(https://png.icons8.com/windows/1600/menu-2.png)切换到下载图标。垂直的三个点图像具有一个onClick侦听器,可将其切换到下载图标,而下载图标具有一个onClick侦听器,可将其下载到表行中。每个图像按钮都有其自己的状态(基于要显示的图像)。在表格组件中,我有一个div,它包装了整个屏幕。单击该div时(基本上,如果您单击图像外部的任何位置),我希望能够将表格中的所有图像重置为三个点。我不确定如何完成此操作,因为有许多子组件,每个子组件都有自己的状态(因此,我认为redux不会起作用)。有没有一种方法可以与表格组件共享每个图像按钮的状态?
这是一些表代码
class ActionButton extends React.Component {
constructor(props) {
super(props);
this.state = {
download: false
};
this.toggle = this.toggle.bind(this);
}
toggle(e) {
e.stopPropagation();
this.setState({
download: !this.state.download
});
}
render() {
return this.state.download ? (
<div>
<img src={Download} width='15%' onClick={(e) => this.props.downloadSong(this.props.song, e)}></img>
</div>
)
: (
<div>
<img src={Dots} width='15%' onClick={(e) => this.toggle(e)} className='image'></img>
</div>
)
}
}
这里有一些ActionButton组件
{{1}}
答案 0 :(得分:2)
您lift your state up在这里。实际上,首先,您不需要ActionButton
组件中的状态。它应该是一个无状态组件。您可以将所有数据保留在父组件中。
我们假设歌曲数据中有一个id
属性。您可以在父组件中跟踪downloadState
,并将这首歌曲的id
添加到此状态对象。然后,您可以将此值传递给ActionComponent
并使用它。另外,您可以将所有功能保留在父组件中。
const songs = [
{ id: "1", name: "Always Blue", artist: "Chet Baker", duration: "07:33" },
{ id: "2", name: "Feeling Good", artist: "Nina Simone", duration: "02:58" },
{ id: "3", name: "So What", artist: "Miles Davis", duration: "09:23" },
]
class App extends React.Component {
state = {
downloadState: {},
}
toggle = ( e, id ) => {
e.stopPropagation();
this.setState( prevState => ({
downloadState: { ...prevState.downloadState, [id]: !prevState.downloadState[id]}
}))
}
downloadSong = ( e, song ) => {
e.stopPropagation();
alert( song.name );
}
resetDownloads = () => this.setState({ downloadState: {}});
render() {
return (
<div onClick={this.resetDownloads}>
<table>
<tbody>
{
songs.map((song, index) => (
<tr key={index}>
<td>{song.name}</td>
<td>{song.artist}</td>
<td>{song.duration}</td>
<td>
<ActionButton
toggle={this.toggle}
song={song}
downloadState={this.state.downloadState}
downloadSong={this.downloadSong}
/>
</td>
</tr>
))
}
</tbody>
</table>
</div>
)
}
}
const ActionButton = props => {
const { downloadState, downloadSong, song, toggle } = props;
const handleToggle = e => toggle(e, song.id);
const handleDownload = e => downloadSong( e, song );
const renderImages = () => {
let images = "";
if ( downloadState[song.id] ) {
images = <p onClick={handleDownload}>Download</p>;
} else {
images = <p onClick={handleToggle}>Dots</p>;
}
return images;
}
return (
<div>{renderImages()}</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
table, th, td {
border: 1px solid black;
}
<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="root"></div>
如果没有任何id
属性,则可以使用索引设置相同的逻辑,但是我认为每个数据都应该有一个id
:)也许可以使用相同的逻辑来代替索引带有歌曲名称,因为它们几乎是唯一的。谁知道:)