我正在尝试将redux集成到现有的反应应用程序中。我正在学习redux。我正在使用钩子。在互联网上有很多使用类组件的例子。我找不到一个如何用函数组件实现这个的例子。
下面的代码不会引发错误。但是,没有调用useEffect
内部的动作。代码不会产生任何输出。我想知道这个电话是否正确。有帮助吗?
Index.js
const store = createStore(rubricReducer, applyMiddleware(thunk));
ReactDOM.render(
<BrowserRouter basename={baseUrl}>
<Provider store={store} > <App /> </Provider>
</BrowserRouter>,
rootElement);
Rubrics.tsx
const mapStateToProps = state => ({
rubrics: state.rubrics.items,
loading: state.rubrics.loading,
error: state.rubrics.error
});
const mapDispatchToProps = (dispatch) => {
return {
getRubrics: () => dispatch(fetchRubrics())
};
}
const Rubrics = (props) => {
const { rubrics, loading, error } = props;
useEffect(() => {
props.dispatch(fetchRubrics());
}, []);
if (error) { return <div>Error! {error.message}</div>; }
if (loading) { return <div>Loading...</div>; }
return (
<ul>
<React.Fragment>
{rubrics.map(rubric => {
return (
<li key={rubric.id}>{rubric.title}</li>
);
})}
</React.Fragment>
</ul>
)
}
export default connect(mapStateToProps, mapDispatchToProps)(Rubrics);
rubritsatstions.tsks:
export function fetchRubrics() {
return dispatch => {
dispatch(fetchRubricsBegin());
axios.get("api/Rubric/Index")
.then(response => {
console.log('success: reading rubrics');
dispatch(fetchRubricsSuccess(response.data));
return response.data;
})
.catch(error => { fetchRubricsFailure(error) });
};
}
export const FETCH_RUBRICS_BEGIN = "FETCH_RUBRICS_BEGIN";
export const FETCH_RUBRICS_SUCCESS = "FETCH_RUBRICS_SUCCESS";
export const FETCH_RUBRICS_FAILURE = "FETCH_RUBRICS_FAILURE";
const fetchRubricsBegin = () => ({
type: FETCH_RUBRICS_BEGIN
})
const fetchRubricsSuccess= (rubrics) => ({
type: FETCH_RUBRICS_SUCCESS,
payload: { rubrics}
})
const fetchRubricsFailure = (error) => ({
type: FETCH_RUBRICS_FAILURE,
payload: {error}
})
rubricReducer.tsx:
import {
FETCH_RUBRICS_BEGIN,
FETCH_RUBRICS_SUCCESS,
FETCH_RUBRICS_FAILURE
} from '../_actions/rubricActions';
const initialState = {
rubrics: [],
loading: false,
error: null
};
const rubricReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_RUBRICS_BEGIN:
return {
...state,
loading: true,
error: null
};
case FETCH_RUBRICS_SUCCESS:
return {
...state,
loading: false,
items: action.payload.rubrics
}
case FETCH_RUBRICS_FAILURE:
return {
...state,
loading: false,
error: action.payload.error,
items: []
};
default:
return state;
}
}
export default rubricReducer;
这里的问题是你使用错误的mapDispatchToProps。您不需要明确设置调度函数,这就是redux为您做的反应。
所以,下面是正确的方法:
// Now you won't be creating a new object every time your component re-renders
const mapDispatchToProps = {
getRubrics: fetchRubrics
}
const Rubrics = (props) => {
const { getRubrics } = props;
// You should always add elements inside your render scope
// to the second array parameter of useEffect to prevent unexpected bugs.
useEffect(() => {
getRubrics();
}, [getRubrics]);
return (
<div>Your component here!</div>
)
}
在您的调度映射中
const mapDispatchToProps = (dispatch) => {
return {
getRubrics: () => dispatch(fetchRubrics())
};
}
因此,而不是调用props.dispatch(fetchRubrics());
只需调用props.getRubrics()
或从道具中破坏此方法
const { rubrics, loading, error, getRubrics } = props;
然后打电话给getRubrics()
以下是正确的代码:
const Rubrics = (props) => {
useEffect(() => {
props.fetchAllRubrics();
}, [])
return (
props.rubrics.map((rubric) => {
return (<RubricCard rubric={rubric} />)
})
)
}
const mapStateToProps = state => ({
error: state.error,
rubrics: state.rubrics,
loading: state.oading
})
const mapDispatchToProps = dispatch => {
return { fetchAllRubrics: () => dispatch(fetchRubricsData()) }
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Rubrics);