Как отправить избыточное действие для загрузки данных внутри useEffect на загрузку страницы - PullRequest
1 голос
/ 11 апреля 2019

Я пытаюсь интегрировать 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;

Ответы [ 3 ]

4 голосов
/ 16 апреля 2019

Проблема в том, что вы используете неправильно mapDispatchToProps.Вам не нужно явно устанавливать функцию диспетчеризации, это то, что реагирует на ваши запросы:

Ниже приведен правильный способ сделать это:

// 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>
  )
}
1 голос
/ 11 апреля 2019

В вашем диспетчере отображения у вас есть

const mapDispatchToProps = (dispatch) => {
    return {
        getRubrics: () => dispatch(fetchRubrics())
    };
}

, поэтому вместо вызова props.dispatch(fetchRubrics()); просто вызовите props.getRubrics() или деструктуризируйте этот метод из реквизита

const { rubrics, loading, error, getRubrics } = props;

и просто позвоните getRubrics()

0 голосов
/ 12 апреля 2019

Ниже правильный код:

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);
...