gpt4 book ai didi

reactjs - Redux store.subscribe() 不会在状态更改时触发

转载 作者:行者123 更新时间:2023-12-04 02:58:45 25 4
gpt4 key购买 nike

我正在开发一个应用程序,用户可以在其中更改输入值,并根据这些值生成一些计算值。在此演示中,我只需要填写三个输入(其值存储在单独文件 data.js 中的数组中),并且只有一个计算为前三个的平均值。

项目结构如下:

src/index.js

import React from "react";
import ReactDOM from "react-dom";
import Block1 from "../components/Block1";
import getStore from "../store";
const store = getStore();

const rootEl = document.getElementById("root");

const render = () => {
ReactDOM.render(<Block1 />, rootEl);
};

render();

store.subscribe(() => {
render();
console.log("not working");
});

组件/Block1.js

import React, { Component } from "react";
import getStore from "../store";
const store = getStore();

function Item(props) {
return (
<tr key={props.id}>
<td>{props.rn}</td>
<td>{props.name}</td>

{props.not !== "" ? (
<td>
<img src={"img/" + props.not} />
</td>
) : (
<td />
)}

{props.isInput ? (
<td>
<input type="text" value={props.val} onChange={props.onChange} />
</td>
) : (
<td>{props.val}</td>
)}

<td>{props.um}</td>
</tr>
);
}

export default class Block1 extends Component {
renderItem(d) {
return (
<Item
key={d.id}
id={d.id}
rn={d.rn}
name={d.name}
not={d.not}
val={d.val}
um={d.um}
isInput={d.isInput}
onChange={e =>
store.dispatch({
type: "changeValue",
payload: {
id: d.id,
val: e.target.value
}
})
}
/>
);
}

render() {
return (
<div>
<h2>Block 1. Initial data for calculation</h2>
<table className="table">
<thead>
<tr>
<th>№</th>
<th>Name</th>
<th>Notation</th>
<th>Value</th>
<th>Unit of measure</th>
</tr>
</thead>
<tbody>{store.getState().map(d => this.renderItem(d))}</tbody>
</table>
</div>
);
}
}

reducers/index.js

import getData from "../data.js";
const data = getData();
const Parser = require("expr-eval").Parser;

export default (state = data, action) => {
if (action.type === "changeValue") {
let changedId = action.payload.id;
// change value in input
let data = state.slice();
let el = data.find(d => d.id === changedId);
el.val = parseFloat(action.payload.val);

// find all id to re-calculate
const toRecalculate = getAllDependentDataId(changedId);

// recalculation
toRecalculate.forEach(r => {
// ... here some calculation logic which gives the result

let el = data.find(d => d.id === r);
el.val = Math.round((result + 0.00001) * 100) / 100;

return data;
});
}
return state;
};

store/index.js

import reducer from "../reducers";
import { createStore } from "redux";
import getData from "../data.js";

export default function getStore() {
const store = createStore(reducer, getData());
return store;
}

完整的例子是here

问题是由于某种原因新值没有在 UI 中更新。 store.subscribe(...) 中的代码不会运行。但是,状态正在发生变化 - 数组中的值已更新 - 我使用 console.log 进行了检查...

请帮我找出问题所在。

最佳答案

您缺少 actions/action creators、connect、provider、mapStateToProps 和 mapDispatchToProps 来自 redux。如果你只有这 4 个值,那么我不会使用 redux,而是将本地状态用作受控组件。

如果你正在尝试使用 redux,那么我会从这里开始。

https://redux.js.org/basics


这是一个使用 redux 解决平均问题的简单示例: https://codesandbox.io/s/422q1znj4w

组件/Block1.js

import React, { Component } from "react";
import { connect } from "react-redux";
import { changeValue, loadData } from "../actions/action";
import getData from "../data";

function Item(props) {
return (
<tr key={props.id}>
<td>{props.rn}</td>
<td>{props.name}</td>

{props.not !== "" ? (
<td>
<img src={"img/" + props.not} />
</td>
) : (
<td />
)}

{props.isInput ? (
<td>
<input type="text" value={props.val} onChange={props.onChange} />
</td>
) : (
<td>{props.val}</td>
)}

<td>{props.um}</td>
</tr>
);
}

class Block1 extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.loadData(getData());
}
renderItem(d) {
console.log(d.val);
return (
<Item
key={d.id}
id={d.id}
rn={d.rn}
name={d.name}
not={d.not}
val={d.val}
um={d.um}
isInput={d.isInput}
onChange={e =>
this.props.changeValue({ id: d.id, value: e.target.value })
}
/>
);
}

render() {
return (
<div>
<h2>Block 1. Initial data for calculation</h2>
<table className="table">
<thead>
<tr>
<th>№</th>
<th>Name</th>
<th>Notation</th>
<th>Value</th>
<th>Unit of measure</th>
</tr>
</thead>
<tbody>{this.props.data.map(d => this.renderItem(d))}</tbody>
</table>
</div>
);
}
}
const mapStateToProps = state => {
return {
data: state.data
};
};
const mapDispatchToProps = dispatch => {
return {
changeValue: item => dispatch(changeValue(item)),
loadData: data => dispatch(loadData(data))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Block1);

actions/action.js

export function changeValue(data) {
return {
type: "changeValue",
data
};
}

export function loadData(data) {
return {
type: "loadData",
data
};
}

reducers/data.js

export function data(state = [], action) {
if (action.type === "loadData") {
return action.data;
} else {
if (action.type === "changeValue") {
let newState = [...state];
newState[action.data.id - 1].val = action.data.value;

let counter = 0;
let sum = 0;

for (let input of newState) {
if (input.isInput) {
sum += parseInt(input.val);
counter++;
}
}
newState[state.length - 1].val = sum / counter;
return newState;
}
}
return state;
}

reducers/rootReducer.js

import { combineReducers } from "redux";
import { data } from "./data";
const rootReducer = combineReducers({
data
});
export default rootReducer;

src/index.js

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import configureStore from "../store";
import Block1 from "../components/Block1";

const store = configureStore();

const rootEl = document.getElementById("root");

ReactDOM.render(
<Provider store={store}>
<Block1 />
</Provider>,
rootEl
);

store/index.js

import { createStore } from "redux";
import rootReducer from "../reducers/rootReducer";

export default function configureStore() {
return createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
}

关于reactjs - Redux store.subscribe() 不会在状态更改时触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51268008/

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