Reactjs 操作未将数据传递给减速器
我有以下设置: Dashboard.jsx:Reactjs 操作未将数据传递给减速器,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我有以下设置: Dashboard.jsx: import React, { Component } from "react"; import { addFlashMessage } from "../actions/flashMessages"; import RoomsList from "./RoomsList"; import PropTypes from "prop-types"; import FlashMessagesList from "../components/flash/F
import React, { Component } from "react";
import { addFlashMessage } from "../actions/flashMessages";
import RoomsList from "./RoomsList";
import PropTypes from "prop-types";
import FlashMessagesList from "../components/flash/FlashMessagesList";
import { connect } from "react-redux";
class Dashboard extends Component {
render() {
return (
<div className="componentContent">
<FlashMessagesList />
<RoomsList addFlashMessage={addFlashMessage} />
</div>
);
}
}
Dashboard.propTypes = {
addFlashMessage: PropTypes.func.isRequired
};
export default connect(null, { addFlashMessage })(Dashboard);
import React, { Component } from "react";
import PropTypes from "prop-types";
class RoomsList extends Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick() {
this.props.addFlashMessage({
type: "success",
text: "You signed up successfully. Welcome."
});
}
render() {
return (
<div className="componentContent" onClick={this.onClick} />
);
}
}
RoomsList.propTypes = { addFlashMessage: PropTypes.func.isRequired };
export default RoomsList;
export function addFlashMessage(message) {
console.log("action called");
return {
type: ADD_FLASH_MESSAGE,
message
};
}
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { BrowserRouter as Router, Route } from "react-router-dom";
// Redux
import { Provider } from "react-redux";
import thunk from "redux-thunk";
import { createStore, applyMiddleware, compose } from "redux";
import rootReducer from "./rootReducer";
const store = createStore(
rootReducer,
compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : f => f
)
);
ReactDOM.render(
<Provider store={store}>
<Router>
<div className="navSwitch">
<Route path="/" component={App} />
</div>
</Router>
</Provider>,
document.getElementById("root")
);
Reducers.js
import { ADD_FLASH_MESSAGE } from "../actions/types";
import shortid from "shortid";
export default (state = [], action = {}) => {
console.log(action);
switch (action.type) {
case ADD_FLASH_MESSAGE:
return [
...state,
{
id: shortid.generate(),
type: action.message.type,
text: action.message.text
}
];
default:
return state;
}
};
index.js:
import React, { Component } from "react";
import { addFlashMessage } from "../actions/flashMessages";
import RoomsList from "./RoomsList";
import PropTypes from "prop-types";
import FlashMessagesList from "../components/flash/FlashMessagesList";
import { connect } from "react-redux";
class Dashboard extends Component {
render() {
return (
<div className="componentContent">
<FlashMessagesList />
<RoomsList addFlashMessage={addFlashMessage} />
</div>
);
}
}
Dashboard.propTypes = {
addFlashMessage: PropTypes.func.isRequired
};
export default connect(null, { addFlashMessage })(Dashboard);
import React, { Component } from "react";
import PropTypes from "prop-types";
class RoomsList extends Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick() {
this.props.addFlashMessage({
type: "success",
text: "You signed up successfully. Welcome."
});
}
render() {
return (
<div className="componentContent" onClick={this.onClick} />
);
}
}
RoomsList.propTypes = { addFlashMessage: PropTypes.func.isRequired };
export default RoomsList;
export function addFlashMessage(message) {
console.log("action called");
return {
type: ADD_FLASH_MESSAGE,
message
};
}
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { BrowserRouter as Router, Route } from "react-router-dom";
// Redux
import { Provider } from "react-redux";
import thunk from "redux-thunk";
import { createStore, applyMiddleware, compose } from "redux";
import rootReducer from "./rootReducer";
const store = createStore(
rootReducer,
compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : f => f
)
);
ReactDOM.render(
<Provider store={store}>
<Router>
<div className="navSwitch">
<Route path="/" component={App} />
</div>
</Router>
</Provider>,
document.getElementById("root")
);
从“React”导入React;
从“react dom”导入react dom;
从“/components/App”导入应用程序;
从“react Router dom”导入{BrowserRouter as Router,Route};
//重演
从“react redux”导入{Provider};
从“redux thunk”导入thunk;
从“redux”导入{createStore,applyMiddleware,compose};
从“/rootReducer”导入rootReducer;
const store=createStore(
减根剂,
谱写(
applyMiddleware(thunk),
window.devToolsExtension?window.devToolsExtension():f=>f
)
);
ReactDOM.render(
,
document.getElementById(“根”)
);
而actions.js
console.log显示为ok,但在reducer.js
中,console.log未被执行,因此只返回默认状态
有人能发现问题出在哪里吗?在
仪表板组件中,您通过道具向组件传递添加FlashMessage
操作,但在组件内部,您使用的是导入的功能,而不是传递的功能。它们看起来是一样的(因为它们实际上是同一函数的不同版本),但由于导入的函数未包装在dispatch()
中,因此对它的调用不会触发Redux操作
修复是显而易见的-您需要在这里使用这个.props.addFlashMessage
:在仪表板中您通过props
将addFlashMessage
操作传递给组件,但在组件内部您使用的是导入的函数,而不是传递的。它们看起来是一样的(因为它们实际上是同一函数的不同版本),但由于导入的函数未包装在dispatch()
中,因此对它的调用不会触发Redux操作
修复是显而易见的-您需要使用this.props.addFlashMessage
此处:
Redux开发工具对于类似的事情是一个很好的帮助-值得使用它只是为了看看某个操作是否真的启动,如果是,至少您知道它在减速器中,如果没有,动作没有被分派Edux dev tools对于类似的事情是一个很好的帮助-值得使用它只是为了看看动作是否真正激发,如果是这样,至少你知道它在减速器中,如果操作未被分派,则会导致失败的道具类型:道具“addFlashMessage”在仪表板中标记为必需,但其值为“未定义”。
当然,因为我的示例返回{actions:addFlashMessage}
。建议使用这种方法,因为通常在组件中有多个操作。您可以返回单个操作,也可以更新propTypes
定义,改为使用actions:propTypes.object.isRequired
。您还需要更新组件内部的操作引用。但这并不是问题的真正原因,因为我的方法可以使用,我们可以在这里阅读:所以问题必须在其他地方。@Xeen您是对的,对不起,不知道这种速记语法。我也被辛普敦搞糊涂了。然而,我看到了问题的真正原因,我现在将更新答案如果你看我的代码,我已经在这样做:)所以这是另一回事。这导致失败的道具类型:道具“addFlashMessage”在仪表板中标记为必需,但其值是“未定义的”。
当然,因为我的示例返回{操作:addFlashMessage}
。建议使用这种方法,因为组件中通常有多个操作。您可以返回单个操作,也可以更新propTypes
定义,使其具有操作:propTypes.object.isRequired
。您还需要更新组件内的操作引用。但这并不是真正的原因我的方法可以用来解决这个问题,我们可以在这里阅读:所以问题必须在其他地方。@Xeen你是对的,对不起,没有意识到这种速记语法。我也被Symptom搞糊涂了。但是我看到了问题的真正原因,我现在会更新答案,如果你看我的代码,我已经在做了:)所以这是一些问题还有一个。