【发布时间】:2020-10-26 16:32:35
【问题描述】:
我正在尝试在我制作的两个组件之间共享状态。根据我的研究,我相信我需要将状态提升到祖先组件,然后将该状态细流到其他组件。作为参考,我添加了一个文件上传器,它将接收一个 json 文件,然后我将有一个通过 json 的逻辑文件循环,然后该数据将被呈现到具有新值的表中。
https://reactjs.org/docs/lifting-state-up.html
我很困惑如何在这些组件之间共享状态并感谢任何批评。
文件上传器.js
import React, { useCallback, useState } from 'react'
import { useDropzone } from 'react-dropzone'
import RoombaClean from './Roomba'
const style = {
margin: '10% 30% 10% 30%',
flex: 1,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: '30px',
borderWidth: 1,
borderRadius: '20px',
borderColor: '#bdbdbd',
borderStyle: 'dashed',
backgroundColor: '#eeeeee',
color: '#bdbdbd',
outline: 'none',
transition: 'border .24s ease-in-out',
};
function FileUploader() {
const [state, setState] = useState("");
const onDrop = useCallback((acceptedFiles) => {
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = () => {
const inputJson =
JSON.parse(reader.result)
console.log(inputJson)
setState(inputJson);
//apply logic to transform json
}
reader.readAsText(file)
})
}, [])
const {getRootProps, getInputProps} = useDropzone({onDrop})
return (
<div {...getRootProps({style})}>
<input {...getInputProps()} value={state}/>
<p>Drag files here, or click to browse</p>
</div>
)
}
export default FileUploader;
Ancestor.js
import React, { useState } from 'react'
import FileUploader from './FileUploader'
import Table from './Table'
function Ancestor() {
const [state, setState] = useState('');
return <>
<FileUploader state={state} />
<Table state={state} />
</>;
}
export default Ancestor;
Table.js
import React from 'react'
function Table() {
return (
<div>
<table className="table">
<thead>
<tr>
<th>Step</th>
<th>Roomba Location</th>
<th>Action</th>
<th>Total Dirt Collected</th>
<th>Total Wall Hits</th>
</tr>
</thead>
<tbody>
{
}
</tbody>
</table>
<h4>Final Position: {}</h4>
<h4>Total Dirt Collected: {}</h4>
<h4>Total Distance Traveled: {}</h4>
<h4>Total Walls Hit: {}</h4>
</div>
)
}
export default Table
【问题讨论】:
-
状态应该简单地作为道具传递下去。除了你的命名(
state和setState非常通用。通常你会想要使用类似products和setProducts的名称)对我来说看起来不错。现在你只需要使用传递给你的子组件的道具。如果父组件中的状态发生更改,它将自动重新渲染并将新状态作为道具传递给您的子组件。此外,状态更新必须通过将回调传递给您的子组件来传播到保存状态的组件。