gpt4 book ai didi

javascript - Redux 的行为不正确

转载 作者:行者123 更新时间:2023-11-29 10:59:27 25 4
gpt4 key购买 nike

我刚学了一点react-redux,就卡在这些我无法理解和修复的问题上至少4天了。

  1. 第一个问题存在,可以在检查员控制台看到(我使用 Chrome)。我在 <div> 有事件处理程序内部 react 组件。它必须在 onClick 调用事件,但它会在每次加载或重新加载站点时触发。

  2. 其次,站在 reducer 函数附近。它在控制台(开发工具)中告诉我,reducers 收到操作“TOGGLE_TILE”并返回未定义而不是对象。应该注意到 reducer 成功接收状态、 Action 属性并在内部进行一些操作,但结果没有正常返回。

    我的 reducer、actions、main、container、presentation 组件和功能提供的代码。请尽可能展开回答,我想了解哪里出了问题,不要在代码中两次犯这个错误。

还有!我使用 redux-thunk 中间件(到 Action 中的功能回调,你知道的)。我里面有:

index.js - 主要组件

const store = createStore(reducer, applyMiddleware(thunk));

ReactDOM.render(
<Provider store={store}>
<AppContainer />
</Provider>,
document.getElementById('root')
);
registerServiceWorker();

Action .js

export function toggle(id){
return{
type: 'TOGGLE_TILE',
id
};
}

export function toggleTile(id){
return dispatch => {
console.log('toggling');
dispatch(toggle(id));
};
}

tiles.js - reducer

var i = 0;

function tiles(state = tilesContainer, action){
var openedTiles = [];
switch (action.type) {
case 'TOGGLE_TILE':
if(i < 2){
console.log('i: '+i);
state.map((value) => {
var newOpen;
if(!value.opened && action.id === value.id){
newOpen = Object.assign({}, value, {
opened: !value.opened
});
openedTiles.push(newOpen);
i++;
console.log(i, value.opened, newOpen, openedTiles);
}
return newOpen, i;
});
}else if(i === 2){
var curr, prev;
openedTiles.map((value) => {
if(!prev){
prev = value;
}else{
curr = value;
console.log("Prev and curr: "+prev, curr);
if(curr.name === prev.name){
var currRes = Object.assign({}, curr, {
disappeared: !curr.disappeared
});
var prevRes = Object.assign({}, prev, {
disappeared: !prev.disappeared
});
return {currRes, prevRes};
} else {
let currRes = Object.assign({}, curr, {
opened: !curr.opened
});
let prevRes = Object.assign({}, prev, {
opened: !prev.opened
})
return currRes, prevRes;
}
}
});
}else{
return state;
}
default:
return state;
}
console.log("tiles: "+state.forEach(value => console.log(value)));
}



const reducers = combineReducers({
tiles
});

export default reducers;

AppContainer.jsx

const mapStateToProps = (state) => {
return {
tiles: state.tiles
};
};

const mapDispatchToProps = (dispatch) => {
return {
toggle: id => {
// console.log(id);
dispatch(toggleTile(id));
}
};
};


class AppContainer extends Component {
constructor(props){
super(props);
}
componentDidMount(){

}
render() {
var prop = this.props;
console.log(prop);
return (
<div>
<AppView prop={prop} />
</div>
);
}
}

export default connect(mapStateToProps, mapDispatchToProps)(AppContainer);

AppView.js

class AppView extends React.Component {
constructor(props){
super(props);
this.state = {
tiles: this.props.prop.tiles,
};
this.showTiles = this.showTiles.bind(this);
this.defineRatio = this.defineRatio.bind(this);
this.toggleTile = this.toggleTile.bind(this);
}
componentDidMount(){
this.defineRatio();

}
componentWillMount(){

}
defineRatio(){
var imgClass;
let tile = document.querySelectorAll('img');
tile.forEach((value) => {
var imgSrc, imgW, imgH;
function defineImage(imgSrc){
var img = new Image();
img.src = imgSrc;
img.onload = function() {
return {
src:imgSrc,
width:this.width,
height:this.height};
};
return img;
}
var x = defineImage(value.src);
x.addEventListener('load',function(){
imgSrc = x.src;
imgW = x.width;
imgH = x.height;
// console.log(value.src, imgW, imgH);
var imgClass = (imgW / imgH > 1) ? 'wide' : 'tall';
value.classList += imgClass;
});
});
}
toggleTile(id){
this.props.prop.toggle(id);
}
showTiles(){
const boxElems = this.state.tiles.map((value, index) => {
var styles = {background: 'black'};
var tileState = value.opened ? '' : styles;
var imgState = value.opened ? 'opened ' : 'closed ';
var elem = <img key={value.id} src={value.src} alt="" className={imgState} />;
var boxElem = <div style={tileState} className="tile-box " onClick={this.toggleTile(value.id)} key={index}>{elem}</div>;
return boxElem;
});
return boxElems;
}
render(){
var tiles = this.showTiles();
return (
<div className="tiles-box">
<div className="tiles">
{tiles}
</div>
</div>
);
}
}

export default AppView;

最佳答案

第一个问题可以通过替换来解决

onClick={this.toggleTile(value.id)}使用 onClick={(e) => this.toggleTile(value.id)} 第一条语句只是立即调用 this.toggleTile(value.id) 并将返回值设置为 OnClick 事件。

关于第二个,你没有从你的 reducer 返回任何东西,因此状态是未定义的。

       if(i < 2){  
console.log('i: '+i);
state.map((value) => {
var newOpen;
if(!value.opened && action.id === value.id){
newOpen = Object.assign({}, value, {
opened: !value.opened
});
openedTiles.push(newOpen);
i++;
console.log(i, value.opened, newOpen, openedTiles);
}
return newOpen, i;
});
}

这是什么return newOpen,我它应该是return newOpen,因为这个返回是在映射函数中,所以你也必须返回映射数组所以使用 return state.map((value) => {

关于javascript - Redux 的行为不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50157222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com