试图通过类似的问题,但没有发现类似的问题。
我正在尝试按照我的应用中的名称和金额实施排序,此事件在此组件中触发:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { sortByExpenseName, sortByExpenseAmount } from '../actions/expensesFilters';
class ExpensesListFilter extends Component {
onSortByExpenseName = () => {
this.props.sortByExpenseName();
};
onSortByExpenseAmount = () => {
this.props.sortByExpenseAmount();
}
render() {
return (
<div>
<span>Expense Name</span>
<button onClick={this.onSortByExpenseName}>Sort me by name</button>
<button onClick={this.onSortByExpenseAmount}>Sort me by amount</button>
</div>
)
}
}
const mapDispatchToProps = (dispatch) => ({
sortByExpenseName: () => dispatch(sortByExpenseName()),
sortByExpenseAmount: () => dispatch(sortByExpenseAmount()),
});
export default connect(null, mapDispatchToProps)(ExpensesListFilter);
为此我使用了以下选择器:
export default (expenses, { sortBy }) => {
return expenses.sort((a, b) => {
if (sortBy === 'name') {
return a.name < b.name ? 1 : -1;
} else if (sortBy === 'amount') {
return parseInt(a.amount, 10) < parseInt(b.amount, 10) ? 1 : -1;
}
});
};
我在我的ExpensesList组件的mapStateToProps函数中运行此选择器:
import React from 'react';
import { connect } from 'react-redux';
import ExpensesItem from './ExpensesItem';
// my selector
import sortExpenses from '../selectors/sortExpenses';
const ExpensesList = props => (
<div className="content-container">
{props.expenses && props.expenses.map((expense) => {
return <ExpensesItem key={expense.id} {...expense} />;
}) }
</div>
);
// Here I run my selector to sort expenses
const mapStateToProps = (state) => {
return {
expenses: sortExpenses(state.expensesData.expenses, state.expensesFilters),
};
};
export default connect(mapStateToProps)(ExpensesList);
此选择器更新我的过滤器减少器,这会导致我的应用程序状态更新:
import { SORT_BY_EXPENSE_NAME, SORT_BY_EXPENSE_AMOUNT } from '../actions/types';
const INITIAL_EXPENSE_FILTER_STATE = {
sortBy: 'name',
};
export default (state = INITIAL_EXPENSE_FILTER_STATE, action) => {
switch (action.type) {
case SORT_BY_EXPENSE_NAME:
return {
...state,
sortBy: 'name',
};
case SORT_BY_EXPENSE_AMOUNT:
return {
...state,
sortBy: 'amount',
};
default:
return state;
}
};
排序事件导致我的状态更新,下面的费用减少器中的费用数组被更新并按选择器排序,但是在我的费用数组状态更新后,ExpensesList组件不会重新呈现。 我希望我的ExpensesList组件做的是使用已排序的费用数组重新呈现并在列表中对ExpensesItem组件进行排序。 它失败的原因是什么?很确定我错过了必不可少的东西,但无法弄清楚是什么。我的费用减少:
import { FETCH_EXPENSES } from '../actions/types';
const INITIAL_STATE = {};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case FETCH_EXPENSES:
return {
...state,
expenses: action.expenses.data,
};
default:
return state;
}
};
所有这些组件都是此父组件的子组件:
import React from 'react';
import ExpensesListFilter from './ExpensesListFilter';
import ExpensesList from './ExpensesList';
const MainPage = () => (
<div className="box-layout">
<div className="box-layout__box">
<ExpensesListFilter />
<ExpensesList />
</div>
</div>
);
export default MainPage;
App.js文件(我运行startExpenseFetch)
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import 'normalize.css/normalize.css';
import AppRouter, { history } from './routers/AppRouter';
import configureStore from './store/configureStore';
import LoadingPage from './components/LoadingPage';
import { startExpenseFetch } from './actions/expensesData';
import './styles/styles.scss';
const store = configureStore();
const jsx = (
<Provider store={store}>
<AppRouter />
</Provider>
);
let hasRendered = false;
const renderApp = () => {
if (!hasRendered) {
ReactDOM.render(jsx, document.getElementById('app'));
hasRendered = true;
}
};
store.dispatch(startExpenseFetch()).then(() => {
renderApp();
});
ReactDOM.render(<LoadingPage />, document.getElementById('app'));
其余文件:
ExpenseItem组件:
import React from 'react';
const ExpenseItem = ({ amount, name }) => (
<div>
<span>{name}</span>
<span>{amount}</span>
</div>
);
export default ExpenseItem;
行动创作者:
expensesData.js
import axios from 'axios';
import { FETCH_EXPENSE } from './types';
// no errors here
const ROOT_URL = '';
export const fetchExpenseData = expenses => ({
type: FETCH_EXPENSE,
expenses,
});
export const startExpenseFetch = () => {
return (dispatch) => {
return axios({
method: 'get',
url: `${ROOT_URL}`,
})
.then((response) => {
dispatch(fetchExpenseData(response));
console.log(response);
})
.catch((error) => {
console.log(error);
});
};
};
expensesFilters.js
import { SORT_BY_EXPENSE_NAME, SORT_BY_EXPENSE_AMOUNT } from './types';
export const sortByExpenseName = () => ({
type: SORT_BY_EXPENSE_NAME,
});
export const sortByExpenseAmount = () => ({
type: SORT_BY_EXPENSE_AMOUNT,
});
configureStores.js文件
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import expensesDataReducer from '../reducers/expensesData';
import expensesFilterReducer from '../reducers/expensesFilters';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export default () => {
const store = createStore(
combineReducers({
expensesData: expensesDataReducer,
expensesFilters: expensesFilterReducer,
}),
composeEnhancers(applyMiddleware(thunk))
);
return store;
};
AppRouter.js文件
import React from 'react';
import { Router, Route, Switch, Link, NavLink } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
import MainPage from '../components/MainPage';
import NotFoundPage from '../components/NotFoundPage';
export const history = createHistory();
const AppRouter = () => (
<Router history={history}>
<div>
<Switch>
<Route path="/" component={MainPage} exact={true} />
<Route component={NotFoundPage} />
</Switch>
</div>
</Router>
);
export default AppRouter;
答案 0 :(得分:0)
你打电话给选择器时输错了吗? :)
// Here I run my selector to sort expenses
const mapStateToProps = (state) => {
return {
expenses: sortExpenses(state.expensesData.expenses, state.expnsesFilters),
};
};
state.expnsesFilters 看起来应该是州。费用过滤器
这是你应该让sortExpenses
选择器抓住自己需要的状态部分并自行完成工作的原因之一。你可以测试它的隔离并避免这样的错误。
答案 1 :(得分:0)
我找到了它发生的原因,在我的选择器中我正在改变我的应用程序的状态。我没有从它返回一个新数组,而是改变旧数组,而不是触发我的vue层重新渲染。修复它现在可以使用了。