state.getStore()或mapStateToProps - React.js / Redux

时间:2016-12-06 09:37:44

标签: javascript reactjs redux

所以我正在构建我的第一个Redux项目来学习它。我只是在中间件记录器中输出更新状态,这样很棒。

现在我正在尝试根据更新的状态更新组件。

显然我在这里错过了一些基本概念......我想我应该绘制mapStateToProps,但我不理解它。

我可以使用一些简单的全球性东西吗?

为什么我控制了store.getState()。引用它有效,但是没有更新组件?

引用组件

import React from 'react';
import { connect } from 'react-redux';
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import promise from 'redux-promise';
import createLogger from 'redux-logger';
import quoteReducer from './reducers/quoteReducer';

const logger = createLogger();
const store = createStore(
  quoteReducer,
  applyMiddleware(thunk, promise, logger)
);

class quote extends React.Component {

    componentWillMount() {
        let req = new XMLHttpRequest();
        req.responseType = "json";

        req.onload = function(){
            store.dispatch({type: "ADD_QUOTE", text: req.response.quote, movie: req.response.author});
        }.bind(this)

        req.open("GET", "http://localhost:3001/quote");
        req.send();
    }

    render(){
        return (
            <div id="quote">
                <h1> "{store.getState().quote}" </h1>
                <h2> -{store.getState().author} </h2>
            </div>
        )
    }

}

export default connect()(quote);

减速器

const quoteReducer = (state = {quote: "", author: ""}, action) => {

    switch (action.type) {
        case 'ADD_QUOTE':
            return {
                quote: action.text,
                author: action.movie
            }

        default:
            return state
    }

}

export default quoteReducer;

ACTION

export const addQuote = (text, movie) => {
    return {
        type: "ADD_QUOTE",
        text,
        movie
    }
}

APP.JS

import React, { Component } from 'react';
import Quote from './quote';
import AnswerInput from './answerInput';
import logo from './logo.svg';
import './App.css';
import './quote.css';
import './answerInput.css';
import './assets/styles/global.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Quote />
        <AnswerInput />
      </div>
    );
  }
}

export default App;

INDEX.JS

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import quoteReducer from './reducers/quoteReducer.js';
import './index.css';

let store = createStore(quoteReducer);

ReactDOM.render(
    <Provider store={store}>        
        <App />
    </Provider>,
    document.getElementById('root')
);

2 个答案:

答案 0 :(得分:2)

@Konstantin Vitkovsky的答案是排序的权利,但不完全正确。

您的原始示例存在一些问题:

首先,您的quote组件应具有大写名称,例如Quote。 React和JSX使用大写来了解您是否尝试呈现组件或单个标记。首字母大写表示它是一个组件,首字母小写表示它必须是标记。

其次,您的组件当前正在直接访问商店,并在其store.getState()方法中调用render。这将是第一次工作,但由于您的组件不知道存储何时更新,因此它不会触发重新渲染。 (另外,在React中,理想情况下render()方法应根据this.propsthis.state呈现内容。)

第三,您 在文件末尾调用React-Redux connect方法,但实际上 无论如何。

最后,你绝对不应该直接在组件中引用商店。您应该在组件树的顶部呈现<Provider store={store}>组件,这将使商店可以访问其中任何连接的组件。

正如@Konstantin Vitkovsky所说,除非您的组件订阅商店,否则您的组件将不知道商店已更新。但是,完全 connect已经为您做了什么。每次商店更新时,connect生成的包装器组件都会重新运行您提供的mapStateToProps功能,并将您返回的数据传递给您的&#34;真实&#34;成分

因此,对于您的示例,您的代码应该大致如下:

import React, {Component} from "react";
import ReactDOM from "react-dom";
import {Provider, connect} from "react-redux";

const store = createStore(rootReducer);

// Normally the store definition and the component would be
// defined in different files
class Quote extends Component {
    render() {
        const {quote, author} = this.props;

        return (
            <div id="quote">
                <h1>{quote}</h1>
                <h2>{author}</h2>
            </div>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        quote : state.quote,
        author : state.author
    };
}

const ConnectedQuote = connect(mapStateToProps)(Quote);


ReactDOM.render(
    <Provider store={store}
        <Quote />
    </Provider>,
    document.getElementById("root")
);

我鼓励您彻底阅读Redux docs - 它们包含很多的良好信息。另外,我在https://github.com/markerikson/react-redux-links保留了一系列关于React,Redux及相关主题的高质量教程和文章的链接。对于任何想要学习生态系统的人来说,它都是一个很好的起点。

答案 1 :(得分:0)

我最终从联系人处获得了一些帮助,这是有效的代码!

import React from 'react';
import { connect } from 'react-redux';
import { addQuote } from './actions';

const mapStateToProps = (state) => {
  const { quote } = state;
  return quote; //This would be the job for selectors (from advanced redux tutorial)
}

const mapDispatchToProps = (dispatch) => ({
  addQuote(req) {
    const { quote, author } = req.response;
    dispatch(addQuote(quote, author)); // Use the action creator
  }
})

class Quote extends React.Component {

    componentWillMount() {
        let req = new XMLHttpRequest();
        req.responseType = "json";

        req.onload = function(){
          this.props.addQuote(req);
        }.bind(this)

        req.open("GET", "http://localhost:3001/quote");
        req.send();

        // the whole bit above is best replaced with a redux-fetch middleware
    }

    render(){
        const {quote, author} = this.props;

        return (
            <div id="quote">
                <h1> "{quote}" </h1>
                <h2> -{author} </h2>
            </div>
        )
    }

}

const ConnectedQuote = connect(mapStateToProps, mapDispatchToProps)(Quote);

export default ConnectedQuote;