状态未映射到组件道具

时间:2019-09-08 11:35:24

标签: reactjs redux connect

我整个上午都被这个错误困扰,所以请在这里帮助我:)

我正在从外部来源获取json并尝试在React组件中显示它。

这是我的代码:

import React, {Component}     from "react";
import {BrowserRouter, Route} from "react-router-dom";

import { Provider } from 'react-redux';
import store from './store'

import Home       from "./pages/Home";
import About      from "./pages/About";
import Contact    from "./pages/Contact";

class App extends Component {
    render() {
        return (
            <Provider store={store}>
                <BrowserRouter>
                    <div className="App">
                        <Route exact path="/" component={Home}/>
                        <Route exact path="/contact" component={Contact}/>
                        <Route exact path="/about" component={About}/>
                    </div>
                </BrowserRouter>
            </Provider>
        );
    }
}

export default App;

反应显示组件:(此组件显示在上方路由器的Home组件中。

import React, {Component}     from "react";
import PropTypes              from "prop-types";
import {Link}                 from "react-router-dom";
import {connect}              from "react-redux";
import {fetchContentIfNeeded} from "../../store/actions";

class Homecatalogus extends Component {
    static propTypes = {
        dispatch: PropTypes.func,
        categories: PropTypes.array,
        pictures: PropTypes.array
    };

    componentDidMount() {
        this.props.dispatch(fetchContentIfNeeded());
    };

    render() {
        const { categories, pictures } = this.props;

        return (
            <div className="Homecatalogus">
                <div className="container">
                    <div className="Hccontent">
                        { categories && categories.map((cat) => (
                            <div className="c-content1">
                                <Link to="#">
                                    <div className="hccontent-img">
                                        <img src="./img/Foto's/Kogellagers/Kogellagers.jpeg" alt="#"/>
                                    </div>
                                    <h3>Kogellagers</h3>
                                    <p>Gespecialiseerd in appendages, kogellagers, koppelingen, slangen en
                                       gereedschappen.</p>
                                </Link> <Link to="#">
                                <div className="hccontent-img">
                                    <img src="./img/Foto's/Koppelingen/Camlocks.jpg" alt="#"/>
                                </div>
                                <h3>Koppelingen</h3>
                                <p>Gespecialiseerd in appendages, kogellagers, koppelingen, slangen en gereedschappen.</p>
                            </Link>
                            </div>
                        ))}
                    </div>
                </div>
            </div>
        );
    }
}

const mapStateToProps = state => {
    console.log(state);
    return {
        categories: state.categories,
        pictures: state.pictures
    };
};

export default connect(mapStateToProps)(Homecatalogus);

这是我的store / index.js:

import {combineReducers, createStore, applyMiddleware} from "redux";
import {composeWithDevTools}                           from "redux-devtools-extension";
import thunk                                           from "redux-thunk";
import reducer                                         from "./reducers";

const middleware = [thunk];

const reducers = combineReducers({reducer});

export default createStore(reducer, composeWithDevTools(applyMiddleware(...middleware)));

actions / index.js:

import sanity from '../../sanity';

export const REQUEST_CONTENT = "REQUEST_CONTENT";
export const RECEIVE_CONTENT = "RECEIVE_CONTENT";

export const requestContent = () => ({
    type: REQUEST_CONTENT
});

export const receiveContent = (content) => ({
    type: RECEIVE_CONTENT,
    categories: content.filter(el => el._type === "category"),
    pictures: content.filter(el => el._type === "sanity.imageAsset")
});

const fetchContent = () => (dispatch) => {
    dispatch(requestContent());
    return sanity.fetch("*[_type == 'category' || _type == 'sanity.imageAsset']")
        .then(content => { dispatch(receiveContent(content)) });
};

export const fetchContentIfNeeded = () => (dispatch, getState) => {
    if (!getState().categories) dispatch(fetchContent());
};

最后是我的减速器:

import { RECEIVE_CONTENT , REQUEST_CONTENT } from "../actions";

export default (state, action) => {
    switch (action.type) {
        case RECEIVE_CONTENT:
            const { categories, pictures } = action;
            return {
                isFetching: false,
                categories,
                pictures
            };

        case REQUEST_CONTENT:
            return {
                isFetching: true,
            };

        default:
            return {
                categories: [],
                pictures: [],
            };
    }
};

我可以看到来自外部源的数据已被接收,并通过reducer等成功地放入了存储中。关键是我没有在组件中看到类别和图片道具。我希望有人能指出我的错误!

1 个答案:

答案 0 :(得分:0)

您尚未添加mapDispatchToProps函数。我们需要使用mapDispatchToProps调度一个动作。因此,redux将重新渲染具有更新状态的组件。

//Update your componentDidMount like this
componentDidMount() {
    //Calls action declared in mapDispatchToProps

    //Here we are calling the fetchContentIfNeeded which is declared 
    //inside mapDispatchToProps to dispatch an action. 
    //Not the one(fetchContentIfNeeded) we imported from actions
    //called fetchContentIfNeeded
    this.props.fetchContentIfNeeded();
};

//Add to your code

//We need to have mapDispatchToProps for dispatch action to reducer
const mapDispatchToProps = dispatch => {
  return {
    // when we call fetchContentIfNeeded it will dispatch action fetchContentIfNeeded(imported from actions) to the reducer.
    fetchContentIfNeeded: () => dispatch(fetchContentIfNeeded()),
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Homecatalogus);