我在使用redux时遇到问题。
当我使用
store.dispatch( addExpense( {description: "Rent"} ) );
在我的app.js文件中,它可以正常工作并添加了对象。但是,当我尝试在单独文件中的组件上下文中使用它时,它就没有。控制台不会引发任何错误。
当我在同一组件中使用其他操作(例如“搜索”)时,它可以正常工作。因此,连接没有问题。似乎由于某些原因它无法更改状态。
//ACTIONS
export const addExpense = ( { description="", amount=0 } = {}) => ({
type: "ADD_EXPENSE",
expense: {
description,
amount
}
})
//REDUCERS
const expenseReducer = ( state = [], action) => {
switch(action.type) {
case "ADD_EXPENSE":
return [...state, action.expense]
case "EDIT_EXPENSE": //<- this works
return state.map( (expense) => {
if (expense.id === action.id)
return {
...expense, ...action.update }
else return expense
} )
default: return state
}
const filterReducer = ( state = {text:""}, action) => {
switch(action.type){
case "FIND_TEXT": //<- this works
return { ...state, text:action.text }
default: return state;
}
}
//COMPONENT
const AddEx = ( props ) => (
<div>
<form onSubmit={(e) => {
e.preventDefault;
props.dispatch(addExpense ( {description: document.getElementById("addedEx").value} ))
console.log(document.getElementById("addedEx").value);
//it shows the correct value in the console but the state stays unchanged
} } >
<input type="text" id="addedEx"/>
<button type="submit">submit</button>
</form>
//SEARACH -> works
<input
type="text" value={props.filter.text}
onChange={(e) => {
props.dispatch(findText({text:e.target.value}))
}}
/>
</div>
)
答案 0 :(得分:0)
您要添加值而不是expenses
的状态,请执行return [...state.expense, action.expense]
//REDUCERS
const expenseReducer = (state = [], action) => {
switch (action.type) {
case 'ADD_EXPENSE':
return {
...state,
expense: [...state.expense, action.expense]
};
case 'EDIT_EXPENSE': //<- this works
return state.map(expense => {
if (expense.id === action.id)
return {
...expense,
...action.update
};
else return expense;
});
default:
return state;
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.0.3/react-redux.min.js"></script>
<script src="http://wzrd.in/standalone/uuid%2Fv1@latest"></script>
<div id="root"></div>
<script type="text/babel">
const { Provider, connect } = ReactRedux;
const { applyMiddleware, createStore, combineReducers } = Redux;
const ADD_EXPENSE = 'ADD_EXPENSE';
function addExpense(payload) {
return { type: ADD_EXPENSE, payload };
}
const initialState = {
expense: [],
};
function rootReducer(state = initialState, action) {
if (action.type === ADD_EXPENSE) {
return {
...state,
expense: [...state.expense, action.payload]
};
}
return state;
}
const store = createStore(rootReducer);
const mapStateToProps = state => {
return { expense: state.expense };
};
function mapDispatchToProps(dispatch) {
return {
addExpense: expense => dispatch(addExpense(expense))
};
}
const ConnectedList = ({ expense, addExpense }) => {
return (
<div>
<ul className="list-group list-group-flush">
{expense.map(el => (
<li className="list-group-item" key={el.id}>
{`${el.description} - $${el.amount}`}
</li>
))}
</ul>
</div>
);
};
const List = connect(
mapStateToProps,
)(ConnectedList);
class ExpenseForm extends React.Component {
state = {
description: '',
amount: 0,
}
handleSubmit = (e) => {
e.preventDefault();
if (!this.state.description || this.state.amount === 0) {
return
}
const { description, amount } = this.state;
this.props.addExpense({
description,
amount,
id: uuidv1()
});
this.setState({
description: '',
amount: 0
})
}
handleInput = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input name="description" placeholder="Description" onChange={this.handleInput} value={this.state.description} />
<input type="number" name="amount" placeholder="Amount" onChange={this.handleInput} value={this.state.amount} />
<input type="submit" />
</form>
)
}
}
const Form = connect(null, mapDispatchToProps)(ExpenseForm);
class App extends React.Component {
render() {
return (
<div>
<List />
<Form />
</div>
);
}
}
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
</script>
答案 1 :(得分:0)
我找到了解决方案。它不起作用,因为 e.preventDefault缺少()。从e.preventDefault更改为e.preventDefault()的简单更改即可解决。愚蠢的错误。