我正在使用React和Redux进行项目。我正在用一个数组更新一个reducer,然后将该数组映射到一个组件中。该组件具有用于有条件地渲染图像的状态。我希望每当reducers状态更新时,此组件状态都将重置为默认状态。
这是减速器:
const reducer = (state={board : []}, action) => {
switch (action.type) {
case 'MAKE_BOARD':
return Object.assign({}, state, {
board: action.payload
})
default:
return state
}
}
这是App.js页面,它调用reducer:
import React, { Component } from 'react';
import './App.css';
import Board from '../Board/Board'
import {connect} from 'react-redux'
const mapReduxStateToProps= (reduxState) => ({
reduxState
})
class App extends Component {
state = {
size : '8',
squareArray : []
}
handleChange =(event) => {
this.setState({
...this.state,
size : Number(event.target.value)
})
console.log(this.state)
}
//This function makes a an array of numbers with 1/4 'X's and 3/4 'O's
boardMaker = (number) => {
this.setState({squareArray:[]});
let size = number*number;
let placeHolderArray = []
for(let i=0; i<size; i++){
placeHolderArray.push('O')
}
for(let j=0; j<size/4;j++){
placeHolderArray[Math.floor(Math.random()*size)] = 'X'
}
this.setState({squareArray: placeHolderArray})
console.log(placeHolderArray)
console.log(this.state.squareArray);
this.props.dispatch({type:'MAKE_BOARD', payload: placeHolderArray})
this.props.dispatch({type: 'SET_SIZE', payload : this.state.size})
}
render() {
return (
<div className="App">
<header className="App-header">
<input onChange={this.handleChange} placeholder='Size'/>
<button onClick={()=>this.boardMaker(this.state.size)}>Make Board</button>
<div className='board' style={{width: 40*this.props.reduxState.size.size}}>
{/* {this.state.squareArray.map(space => {
return(
<div className='square'>{space}</div>
)
})} */}
{JSON.stringify(this.props.reduxState)}
{this.props.reduxState.reducer.board.map((space,index) =>
<Board keys={index} id={space}/>
)
}
</div>
</header>
</div>
);
}
}
export default connect(mapReduxStateToProps)(App);
这是将reducer映射到的board.js:
import React, { Component } from 'react';
import './Board.css'
import { connect } from 'react-redux';
const mapReduxStateToProps = (reduxState) => ({reduxState})
class Board extends Component {
state = {
clicked: false,
displayFlag: false,
counter: 0,
}
imageDisplay= () => {
if(!this.state.clicked && !this.state.displayFlag){
return <img key={this.props.id} src='images/Frog-1.png' alt='Not Clicked'/>
} else if(this.state.displayFlag){
return <img src='images/Yellow.png' alt='None' />
} else {
return this.state.counter;
}
}
handleMouseDown = e => {
document.oncontextmenu = function() {
return false;
}
e = e || window.event;
//console.log(e.which)
console.log(this.state)
switch(e.which) {
case 1 : this.showNumber(); break;
case 2 : break;
case 3 : this.displayFlag(); return false;
default: break;
}
}
displayFlag= () => {
console.log('running')
this.setState({...this.state, displayFlag : !this.state.displayFlag })
return this.state.displayFlag;
}
showNumber= () => {
console.log('run')
let Xcounter = 0;
let edge = Math.sqrt(this.props.reduxState.reducer.board.length)
console.log(edge)
let keys = this.props.keys
let board = this.props.reduxState.reducer.board
let minX = keys%edge === 0 ? 0 : -1;
let maxX = keys%edge === (edge-1) ? 0 : 1;
let minY = Math.floor(keys/edge) == 0 ? 0 : -1;
let maxY = Math.floor(keys/edge) == (edge-1) ? 0 : 1;
for(let x = minX; x <= maxX; x++){
for(let y = minY; y<=maxY; y++){
if(board[keys+x+(y*edge)]=== 'X'){
Xcounter++
}
}
}
if(this.props.id === 'X'){
this.setState({...this.state, clicked: true, counter: 'X'})
return this.state.counter;
}
this.setState({...this.state, clicked: true, counter: Xcounter})
return this.state.counter;
}
render() {
return (
<div className="App">
<div onMouseDown={()=>this.handleMouseDown()} className='square'>{this.imageDisplay()}</div>
</div>
);
}
}
export default connect(mapReduxStateToProps)(Board);
我希望在减速器更新时重置板上的本地状态。我可能可以通过向reducer添加属性并在组件中使用它们来做到这一点,但我希望有更好的方法。
答案 0 :(得分:1)
查看用例-您需要在每个MAKE_BOARD
操作中清空本地状态。
这是我想到的两种方法-
componentWillReceiveProps
/ getDerivedStateFromProps
/ componentDidUpdate
,然后清空您的道具本地状态。RESET_ACTION_NAME
的行上创建一个单独的操作,该操作将在每次更新时返回您的初始状态(为空)。但是要使其正常运行,您需要将本地状态作为对象放置在redux存储中。PS:如果您知道重置状态的操作范围有限,则无需将状态放入存储中。但是,如果您知道此操作跨越多个组件,则可以考虑将本地状态转换为redux存储对象。
答案 1 :(得分:0)
这有点涉及设计意见领域,但是我认为处理此问题的最直接方法是将电路板的状态也置为redux而不是局部状态(可能在同一商店的独立减速器中),因为(如果我理解正确的话)您是在说要根据“ MAKE_BOARD”操作更改其状态。
另一种替代方法是在redux状态下包含一个整数板ID,每次重新制作该板时,该ID都会增加。然后,如果您将其用作开发板的“关键”属性,我相信这将导致它自动重置,因为它将卸载上一个开发板并创建一个新的开发板。
如果您想要更多有关此操作的实现细节,建议将代码版本放入Codepen或codesandbox中,并在您的问题中共享它(但是最好包含大多数相关代码)直接在您的问题文本中。)