我正在尝试将redux集成到现有的react应用程序中。我正在学习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);
rubricActions.tsx:
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;
答案 0 :(得分:10)
有了hooks自v7.1.0起提供的react-redux,现在就可以不用mapStateToProps
和mapDispatchToProps
来写了。
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
const Rubrics = () => {
const dispatch = useDispatch();
const { rubrics, loading, error } = useSelector(
state => ({
error: state.error,
rubrics: state.rubrics,
loading: state.loading
})
);
useEffect(() => {
dispatch(fetchRubrics());
}, [dispatch]);
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>
)
};
答案 1 :(得分:3)
这里的问题是您使用的mapDispatchToProps错误。您无需显式设置调度功能,这就是react 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>
)
}
答案 2 :(得分:1)
在调度映射中,您拥有
const mapDispatchToProps = (dispatch) => {
return {
getRubrics: () => dispatch(fetchRubrics())
};
}
因此,您无需调用props.dispatch(fetchRubrics());
,而只需调用props.getRubrics()
或从道具中破坏此方法即可
const { rubrics, loading, error, getRubrics } = props;
然后致电getRubrics()
答案 3 :(得分:0)
下面是正确的代码:
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);