所以我正在构建我的第一个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')
);
答案 0 :(得分:2)
@Konstantin Vitkovsky的答案是排序的权利,但不完全正确。
您的原始示例存在一些问题:
首先,您的quote
组件应具有大写名称,例如Quote
。 React和JSX使用大写来了解您是否尝试呈现组件或单个标记。首字母大写表示它是一个组件,首字母小写表示它必须是标记。
其次,您的组件当前正在直接访问商店,并在其store.getState()
方法中调用render
。这将是第一次工作,但由于您的组件不知道存储何时更新,因此它不会触发重新渲染。 (另外,在React中,理想情况下render()
方法应仅根据this.props
和this.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;