reactjs - Ovntad beteende efter tillståndsförändring i React-komponent
RenderImages = (): React.ReactElement => {
let selected = this.state.results.filter(x=>this.state.selectedGroups.includes(x.domain))
console.log(selected)
return(
<div className="results_wrapper">
{selected.map((r,i)=>{
let openState = (this.state.selectedImage==i)?true:false;
return(
<RenderPanel panelType={PanelType.large} openState={openState} title={r.domain+'.TheCommonVein.net'} preview={(openIt)=>(
<div className="result" onClick={openIt} style={{ boxShadow: theme.effects.elevation8}}>
<img src={r.url} />
</div>
)} content={(closeIt)=>(
<div className="panel_wrapper">
<div className="panel_content">{r.content}</div>
{this.RenderPostLink(r.domain,r.parent)}
<div onClick={()=>{
closeIt();
this.setState({selectedImage:2})
console.log('wtfff'+this.state.selectedImage)
}
}>Next</div>
<img src={r.url} />
</div>
)}/>
)
})}
</div>
)
}
När jag ändrar tillståndet för 'selectedImage', förväntar jag mig att variabeln 'openState' ska rendera annorlunda inom min map()-funktion. Men det gör den inte.
Console.log visar att tillståndet faktiskt ändrades.
Och vad som är ännu märkligare är att om jag kör "this.setState({selectedImage:2})" inom componentsDidMount(), så renderas allt precis som förväntat.
Varför svarar detta inte på min statusändring?
Uppdatera
Jag har försökt sätta openState i min komponentens tillståndsvariabel, men det hjälper inte heller:
RenderImages = (): React.ReactElement => {
let selected = this.state.results.filter(x=>this.state.selectedGroups.includes(x.domain))
console.log(selected)
let html = selected.map((r,i)=>{
return(
<RenderPanel key={i} panelType={PanelType.large} openState={this.state.openState[i]} title={r.domain+'.TheCommonVein.net'} preview={(openIt)=>(
<div className="result" onClick={openIt} style={{ boxShadow: theme.effects.elevation8}}>
<img src={r.url} />
</div>
)} content={(closeIt)=>(
<div className="panel_wrapper">
<div className="panel_content">{r.content}</div>
{this.RenderPostLink(r.domain,r.parent)}
<div onClick={()=>{
closeIt();
let openState = this.state.openState.map(()=>false)
let index = i+1
openState[index] = true;
this.setState({openState:openState},()=>console.log(this.state.openState[i+1]))
}
}>Next</div>
<img src={r.url} />
</div>
)}/>
)
})
return(
<div className="results_wrapper">
{html}
</div>
)
}
https://codesandbox.io/s/ecstatic-bas-1v3p9?file=/src/Search.tsx
För att testa, tryck bara på enter i sökrutan. Klicka sedan på 1 av 3 av resultaten. När du klickar på 'Nästa' ska fönstret stängas och nästa öppnas. Det är det jag försöker åstadkomma här.
Svar #1
@Spitz var på rätt väg med sitt svar, även om han inte följde igenom till den fullständiga lösningen.
Problemet du har är att panelens useBoolean inte uppdaterar sitt tillstånd baserat på värdet openState som förs ner.
Om du lägger till följande kod i panel.tsx, kommer allt att fungera som du beskrev:
React.useEffect(()=>{
if(openState){
openPanel()
}else{
dismissPanel();
}
},[openState, openPanel,dismissPanel])
Detta gör att en effekt ställs in för att synkronisera isOpen-tillståndet i RenderPanel med openState som skickas som en prop till RenderPanel. På så sätt, medan panelen till största delen styr sig själv, om föräldern ändrar openState, kommer det att uppdateras.
Arbetande sandlåda
Svar #2
Jag tror att det är för att du sätter openState i din map-funktion, efter att den redan har körts. Jag förstår att du tycker att funktionen borde rendera om och sedan kommer loopen att köras en gång till, men jag tror att du behöver sätta openState i en funktion utanför render.
