正如标题所述,当我的组件状态改变时,子组件不会重新渲染。
class App extends Component {
constructor() {
super()
this.state = {
url: ""
}
this.handleWorkerSelect = this.handleWorkerSelect.bind(this)
}
handleWorkerSelect(url) {
this.setState({ url })
}
render() {
return (
<div className="App">
<Workers className="workers" handleClick={this.handleWorkerSelect}/>
<HermesWorker url={this.state.url}/>
</div>
)
}
}
const Workers = (props) => {
return (
<div>
<button onClick={() => props.handleClick("http://localhost:5000/api")}>Worker 1</button>
<button onClick={() => props.handleClick("http://localhost:2000/api")}>Worker 2</button>
</div>
)
}
export default App
这是hermesworker.js
class HermesWorker extends Component {
constructor() {
super()
this.state = {
items: [],
visited: [{name: "This Drive", path: "@back", root: ""}]
}
this.handleFolderClick = this.handleFolderClick.bind(this)
this.handleFileClick = this.handleFileClick.bind(this)
}
componentDidMount() {
if (this.props.url.length === 0) return
fetch(this.props.url)
.then(res => res.json())
.then(items => this.setState({ items }))
}
render() {
const folders = this.state.items.map((item) => {
if (!item.isfile) {
return <Card handleClick={this.handleFolderClick} root={item.root} path={item.path} isfile={item.isfile} name={item.name} size={item.size}/>
}
})
const files = this.state.items.map((item) => {
if (item.isfile) {
return <Card handleClick={this.handleFileClick} root={item.root} path={item.path} isfile={item.isfile} name={item.name} s ize={item.size}/>
}
})
const pathButtons = this.state.visited.map((item) => {
return <PathButton handleClick={this.handleFolderClick} root={item.root} path={item.path} name={item.name}/>
})
return (
<div>
{pathButtons}
<div className="flex-container">
{folders}
{files}
</div>
</div>
)
}
}
本质上,问题在于没有重新渲染HermesWorker组件以使用新的url属性。我不确定为什么会这样,因为例如在hermesworker中,它会渲染在状态更改期间确实会重新渲染的其他子组件。
任何信息都会受到赞赏
编辑进行了更新,以添加hermes worker,该文件超过100行,所以我剪切掉了,只粘贴了我认为对该问题很重要的内容,如果需要可以提供更多内容
答案 0 :(得分:2)
我测试了该代码,它似乎运行良好。您能否提供HermesWorker组件中设置的内容?
编辑:您需要在组件更新时使用setState
设置状态。为此,您可能会寻找componentDidUpdate
,它将在每次更新时运行。这不同于componentDidMount
,后者(希望)将运行一次,然后组件可以更新并重新渲染,但是重新渲染它不被视为“安装”。因此,您可以尝试以下方法:
constructor(props) {
super(props);
this.state = {
url: '',
items: [],
visited: [{name: "This Drive", path: "@back", root: ""}]
}
this.fetchData = this.fetchData.bind(this);
}
componentDidMount() {
//Mount Once
}
componentDidUpdate(prevProps, prevState) {
if (this.state.url !== this.props.url) {
this.setState({url: this.props.url});
// Url state has changed.
}
if(prevState.url !== this.state.url){
//run your fetch
this.fetchData();
}
}
fetchData(){
if (this.props.url.length === 0) return
fetch(this.props.url)
.then(res => res.json())
.then(items => this.setState({ items }));
}
注意:我将提取功能移到了自己的功能上,但这完全取决于您。
还要注意,我在状态中添加了url。请确保保持道具摆放状态,以免发生意外行为。
编辑2:componentDidUpdate
将把prevProps
和prevState
作为参数。使用prevProps
,您可以访问上次更新中的任何道具;而使用prevState
,您可以猜测,您可以访问任何内容-状态为。 “在先前的更新中”是指在更新执行之前。