我无法将商店提供给儿童组件。
这个设置是一个以Symfony作为后端的SPA,但这不应该对此有所影响。
Webpack的入口点是文件:
/client/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware, compose } from 'redux';
import ReduxPromise from 'redux-promise';
import Root from './App';
import registerServiceWorker from './registerServiceWorker';
import reducers from './pages/combine_reducers';
let composeEnhancers = typeof(window) !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(
reducers,
composeEnhancers(
applyMiddleware(ReduxPromise)
)
)
ReactDOM.render(
<Root store={store} />
, document.querySelector('#root')
);
registerServiceWorker();
这样的应用程序位于:
/client/App.js
import React from 'react';
import PropTypes from 'prop-types';
import { Provider } from 'react-redux';
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom';
import HomePage from './pages/home/';
import AccountPage from './pages/account/';
const Root = ({ store }) => {
return(
<Provider store={store}>
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to React</h1>
</header>
<Router>
<div>
<Link to="/account">Account</Link>
<Link to="/">Home</Link>
<div>
<Switch>
<Route path="/account" component={AccountPage} />
<Route path="/" component={HomePage} />
</Switch>
</div>
</div>
</Router>
</div>
</Provider>
)
}
Root.propTypes = {
store: PropTypes.object.isRequired
}
export default Root;
到目前为止一切顺利。该商店在App.js中可用。 但事实并非如此。正如您所看到的,我尝试使用connect()创建商店。
/client/pages/home/index.js
import React from 'react';
import { connect } from 'react-redux';
import Register from '../common/register/';
import PropTypes from 'prop-types';
class Home extends React.Component {
constructor(props){
super(props)
console.log(props);
}
render() {
return (
<div>
<h1> Hello World from home! </h1>
<Register />
</div>
);
}
}
Home.propTypes = {
store: PropTypes.object.isRequired
}
const mapStateToProps = (state) => {
return {
store: state.store,
}
}
export default connect(mapStateToProps)(Home)
在较低级别,注册组件,我能够提交表单,但商店不可用,我无法捕获来自服务器的响应。
/client/pages/common/register/index.js
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import RegisterForm from './containers/register';
import { actionSubmitRegister } from './actions/';
import PropTypes from 'prop-types';
class Register extends React.Component{
constructor (props) {
super(props);
this.state = {
registerResponse: '',
}
this.onSubmitRegister = this.onSubmitRegister.bind(this);
}
onSubmitRegister (event) {
event.preventDefault();
let submitForm = new Promise((resolve, reject) => {
actionSubmitRegister(this.props.form.RegisterForm.values);
});
submitForm.then((response) => {
console.log('response',response);
this.setState({registerResponse: this.props.submit_register.data});
console.log('registerResponse', this.state.registerResponse);
}).catch((error) => {
console.log(error);
});
}
render(){
return (
<div>
<div>
<RegisterForm
submitRegister={this.onSubmitRegister}
/>
<h3>{this.state.registerResponse}</h3>
</div>
</div>
)
}
}
/*
Register.propTypes = {
store: PropTypes.object.isRequired
}
*/
const mapStateToProps = (state) => {
return {
form: state.form,
submit_register: state.submit_register,
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators({actionSubmitRegister}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Register);
答案 0 :(得分:2)
在mapStateToProps
中映射store: state.store
,但一般情况下,您使用此方法将单个道具从您的状态映射到组件中的道具,而不是映射整个商店(如果可能的话)。
例如:
form: state.form
答案 1 :(得分:0)
您无法访问道具中的商店对象的原因是因为您没有通过道具传递它。 来自react-redux库的提供程序使元素树中的所有子项都可以使用它。商店通过React的上下文API提供,而不是通过道具。
&#34; Context旨在共享可被视为React组件树的“全局”数据。&#34;
因此,在Provider的子组件中,我们现在可以执行类似
的操作render() {
const { store } = this.context;
console.log(store)
return(
...
)
}
这与react-redux的连接HOC能够访问商店以及随后mapStateToProps或使用商店的调度方法mapDispatchToProps的方式相同。
我认为Provider要求它的子元素是React组件。 请查看此tutorial以获得更深入的解释。
答案 2 :(得分:0)
在我上面收到的输入之后,我查看了我的代码并开始工作。
实际上主要问题是在/client/pages/common/register/index.js文件中,但是我发布了整个链以供参考:
/client/index.js
无需改变
/client/App.js
对propTypes的引用似乎没有必要,所以我把它们拿出来了。
import React from 'react';
import { Provider } from 'react-redux';
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom';
import HomePage from './pages/home/';
import AccountPage from './pages/account/';
const Root = ({ store }) => {
return(
<Provider store={store}>
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to React</h1>
</header>
<Router>
<div>
<Link to="/account">Account</Link>
<Link to="/">Home</Link>
<div>
<Switch>
<Route path="/account" component={AccountPage} />
<Route path="/" component={HomePage} />
</Switch>
</div>
</div>
</Router>
</div>
</Provider>
)
}
export default Root;
/client/pages/home/index.js
这里似乎不需要propTypes和connect()。
import React from 'react';
import Register from '../common/register/';
class Home extends React.Component {
constructor(props){
super(props)
}
render() {
return (
<div>
<h1> Hello World from home! </h1>
<Register />
</div>
);
}
}
export default Home;
/client/pages/common/register/index.js
这里的主要问题是onSubmitRegister()方法。承诺未正确设置,我直接引用该操作而不是使用this.props。 React似乎不喜欢那样。
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import RegisterForm from './containers/register';
import { actionSubmitRegister } from './actions/';
class Register extends React.Component{
constructor (props) {
super(props);
this.state = {
registerResponse: '',
}
this.onSubmitRegister = this.onSubmitRegister.bind(this);
}
onSubmitRegister (event) {
event.preventDefault();
let submitForm = new Promise((resolve) => {
resolve(this.props.actionSubmitRegister(this.props.form.RegisterForm.values));
});
submitForm.then((result) => {
let data = result.payload.data;
this.setState({registerResponse: data.message});
}).catch((error) => {
console.log(error);
});
}
render(){
return (
<div>
<div>
<RegisterForm
submitRegister={this.onSubmitRegister}
/>
<h3>{this.state.registerResponse}</h3>
</div>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
form: state.form,
submit_register: state.submit_register,
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators({actionSubmitRegister}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Register);