Redux 存储未连接 [英] Redux store not connected
问题描述
我正在从头开始开发 Reactjs Web 应用程序,但遇到了需要帮助的棘手情况.每当我离开特定 url 并返回时,我的 redux 商店似乎没有连接.
routes.js
const RouteList = () =>(<主要><开关><Route path="/abc/" 精确组件={withRouter(HomePage)}/><Route path="/abc/xyz" 精确组件={withRouter(XYZPage)}/><Redirect from="/" to="/abc/"/><路由组件={Error}/></开关></main>);导出默认路由列表;
App.js
class App 扩展 React.Component {构造函数(道具){超级(道具);this.state = {};}使成为 () {返回 (<路由器历史={browserHistory}><div><标题/><路由列表/><页脚/>
</路由器>);}}导出默认应用程序;
Header.js
const Header = () =>{返回 (<Navbar expand="md"><NavbarBrand tag={NavLink} to="/"><img src={brandImage} style={{marginRight: "0", width: "40px", height: "40px"}}/><strong style={{color: "#457B9D"}} >;数据</NavbarBrand><Nav className="mr-auto" 导航栏><导航项目><NavLink className="nav-link" to={"/abc/xyz"} >XYZ</NavLink></NavItem></导航></导航栏>);};导出默认 withRouter(Header);
当我点击 NavLink 时,它会带我到 url:/"abc/xyz",它会带我到 XYZPage.js
XYZPage.js
class XYZPage 扩展 React.Component {构造函数(道具,上下文){超级(道具,上下文);this.state = {活动标签:1"};this.toggle = this.toggle.bind(this);}切换(标签){if (this.state.activeTab !== tab) {this.setState({activeTab:选项卡});}}使成为 () {返回 (<主要><div className="container-fluid pt-3"><导航标签><导航项目><导航链接className={classnames({active: this.state.activeTab === "1"})}onClick={() =>{this.toggle("1");}} >AAA</NavLink></NavItem><导航项目><导航链接className={classnames({active: this.state.activeTab === "2"})}onClick={() =>{this.toggle("2");}} >BBB</NavLink></NavItem><导航项目><导航链接className={classnames({active: this.state.activeTab === "3"})}onClick={() =>{this.toggle("3");}} >CCC</NavLink></NavItem></导航><TabContent activeTab={this.state.activeTab}><TabPane tabId="1"><行><AAAPage/></行></TabPane><TabPane tabId="2"><行><BBBPage/></行></TabPane><TabPane tabId="3"><行><CCCPage/></行></TabPane></TabContent>
</main>);}}导出默认 withRouter(XYZPage);
AAAPage, BBBPage &CCCPage 是需要预先填充下拉列表的组件,我在下面的 index.js 中声明:
index.js
const store = configureStore();store.dispatch(loadAAA());store.dispatch(loadBBB());store.dispatch(loadCCC());使成为((<提供者商店={商店}><浏览器路由器><应用程序/></BrowserRouter></提供者>), document.getElementById('app'));
loadAAA, loadBBB &loadCCC 都是 thunk
configureStore() 方法是这样的:
导出默认函数 configureStore(initialState) {返回创建商店(根减速器,初始状态,composeWithDevTools(applyMiddleware(thunk, reduxImmutableStateInvariant()),));}
为了缩短这篇文章,我给出了我的 AAAPage 示例,因为其他页面的结构相似:
AAAPage.js:
class AAAPage extends React.Component {构造函数(道具,上下文){超级(道具,上下文);this.state = {...};}componentWillReceiveProps(nextProps) {...}使成为() {[...]返回 (<容器流体><行><AAA输入表单//来自Store的数据传递到这里/></行>{子组件}</容器>);}}AAAPage.propTypes = {数据:PropTypes.array};函数 mapStateToProps(state, ownProps) {让数据 = [];如果(state.AAAReducer.length > 0){数据 = state.AAAReducer;}返回 {数据:数据};}导出默认 withRouter(connect(mapStateToProps)(AAAPage));
AAAReducer.js:
导出默认函数 AAAReducer(state=initialState.AAAList, action) {开关(动作.类型){案例类型.LOAD_AAA_SUCCESS:返回 action.AAAList;默认:返回状态;}}
AAAAction.js:
导出函数 loadAAASuccess(AAAList) {返回 {类型:types.LOAD_AAA_SUCCESS,AAAList: AAAlList};}//重击导出函数 loadAAA() {//thunk 总是会返回一个接受调度的函数返回函数(调度){返回 apiCall("ALL").then(response => {调度(loadAAASuccess(response.data.AAA));}).catch(错误=>{抛出(错误);});};}
initialState.js:
出口默认{AAAList: [],BBBList: [],CCC列表:[]};
在这一点上,我相信我为我的代码提供了足够的背景知识.我在设计这个 redux 商店时遵循了教程,但我不确定为什么当我从/abc/xyz"导航到/abc"并返回时,或者当我从/abc"导航到/abc/xyz"时,我的尽管我在 index.js 中调用了 loadAAA() 方法,但商店是空的.所有其他页面也会受到影响.但是,当我直接点击/abc/xyz"时,我的商店已连接并且我的下拉列表已填充.怎么了?是因为我的生命周期方法吗?
我正在使用 react v15.6.2、redux v3.7.2 &redux-thunk v2.3.0.
谢谢指导.
你只在 index.js
的顶层调用 loadAAA
,当你的页面加载.如果您想在每次 XYZPage
页面呈现时发送它,请放入 XYZ 的 componentDidMount
I am developing a Reactjs web application from scratch and encountered a tricky situation which i need help with. Whenever i navigate away from a particular url and navigate back, my redux store does not seem to be connected.
routes.js
const RouteList = () => (
<main>
<Switch>
<Route path="/abc/" exact component={withRouter(HomePage)} />
<Route path="/abc/xyz" exact component={withRouter(XYZPage)} />
<Redirect from="/" to="/abc/" />
<Route component={Error} />
</Switch>
</main>
);
export default RouteList;
App.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render () {
return (
<Router history={browserHistory}>
<div>
<Header />
<RouteList />
<Footer />
</div>
</Router>
);
}
}
export default App;
Header.js
const Header = () => {
return (
<Navbar expand="md">
<NavbarBrand tag={NavLink} to="/">
<img src={brandImage} style={{marginRight: "0", width: "40px", height: "40px"}} /><strong style={{color: "#457B9D"}} >Datum</strong>
</NavbarBrand>
<Nav className="mr-auto" navbar>
<NavItem>
<NavLink className="nav-link" to={"/abc/xyz"} >XYZ</NavLink>
</NavItem>
</Nav>
</Navbar>
);
};
export default withRouter(Header);
When i hit the NavLink which will take me to url: /"abc/xyz", it will take me to XYZPage.js
XYZPage.js
class XYZPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
activeTab: "1"
};
this.toggle = this.toggle.bind(this);
}
toggle(tab) {
if (this.state.activeTab !== tab) {
this.setState({
activeTab: tab
});
}
}
render () {
return (
<main>
<div className="container-fluid pt-3">
<Nav tabs>
<NavItem>
<NavLink
className={classnames({active: this.state.activeTab === "1"})}
onClick={() => {this.toggle("1"); }} >
AAA
</NavLink>
</NavItem>
<NavItem>
<NavLink
className={classnames({active: this.state.activeTab === "2"})}
onClick={() => {this.toggle("2"); }} >
BBB
</NavLink>
</NavItem>
<NavItem>
<NavLink
className={classnames({active: this.state.activeTab === "3"})}
onClick={() => {this.toggle("3"); }} >
CCC
</NavLink>
</NavItem>
</Nav>
<TabContent activeTab={this.state.activeTab}>
<TabPane tabId="1">
<Row>
<AAAPAge/>
</Row>
</TabPane>
<TabPane tabId="2">
<Row>
<BBBPage/>
</Row>
</TabPane>
<TabPane tabId="3">
<Row>
<CCCPage/>
</Row>
</TabPane>
</TabContent>
</div>
</main>
);
}
}
export default withRouter(XYZPage);
Each of the AAAPage, BBBPage & CCCPage are components which needs to have some pre-populated dropdowns which i declared in my index.js below:
index.js
const store = configureStore();
store.dispatch(loadAAA());
store.dispatch(loadBBB());
store.dispatch(loadCCC());
render((
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
), document.getElementById('app'));
loadAAA, loadBBB & loadCCC are all thunks
The configureStore() method is as such:
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
composeWithDevTools(
applyMiddleware(thunk, reduxImmutableStateInvariant()),
)
);
}
To shorten this post i give a sample of my AAAPage as the others are of similar structure:
AAAPage.js:
class AAAPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {...};
}
componentWillReceiveProps(nextProps) {...}
render() {
[...]
return (
<Container fluid>
<Row>
<AAAInputForm
// Data from Store is passed here
/>
</Row>
{ChildComponent}
</Container>
);
}
}
AAAPage.propTypes = {
DATA: PropTypes.array
};
function mapStateToProps(state, ownProps) {
let DATA = [];
if (state.AAAReducer.length > 0) {
DATA = state.AAAReducer;
}
return {
DATA: DATA
};
}
export default withRouter(connect(mapStateToProps)(AAAPage));
AAAReducer.js:
export default function AAAReducer(state=initialState.AAAList, action) {
switch(action.type) {
case types.LOAD_AAA_SUCCESS:
return action.AAAList;
default:
return state;
}
}
AAAAction.js:
export function loadAAASuccess(AAAList) {
return {
type: types.LOAD_AAA_SUCCESS,
AAAList: AAAlList
};
}
// thunk
export function loadAAA() {
// A thunk will always return a function that accepts a dispatch
return function(dispatch) {
return apiCall("ALL").then(response => {
dispatch(loadAAASuccess(response.data.AAA));
}).catch(error => {
throw(error);
});
};
}
initialState.js:
export default {
AAAList: [],
BBBList: [],
CCCList: []
};
At this point i believe i provided enough background to my code. I followed tutorials when designing this redux store and I am not sure why when i navigate from "/abc/xyz" to "/abc" and back, or when i navigate to "/abc/xyz" from "/abc", my stores are empty although i called the loadAAA() method at my index.js. All the other pages are affected as well. However, when i hit "/abc/xyz" directly, my stores are connected and my dropdowns are populated. What is happening? Is it because of my lifecycle methods?
I am using react v15.6.2, redux v3.7.2 & redux-thunk v2.3.0.
Thanks for the guidance.
You only call loadAAA
at the top level of index.js
, which only executes once when your page loads. If you want to dispatch it every time your XYZPage
page renders, put in XYZ's componentDidMount
这篇关于Redux 存储未连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!