Я разрабатываю веб-приложение Reactjs с нуля и столкнулся со сложной ситуацией, в которой мне нужна помощь. Всякий раз, когда я ухожу с определенного URL-адреса и возвращаюсь назад, мой магазин избыточности, похоже, не подключен.
маршруты.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;
Заголовок.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);
Когда я нажму NavLink, который приведет меня к URL-адресу: /"abc/xyz", он приведет меня к 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);
Каждый из AAAPage, BBBPage и CCCPage является компонентом, который должен иметь некоторые предварительно заполненные выпадающие списки, которые я объявил в своем index.js ниже:
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 — все это преобразователи
Метод configureStore() выглядит так:
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
composeWithDevTools(
applyMiddleware(thunk, reduxImmutableStateInvariant()),
)
);
}
Чтобы сократить этот пост, я привожу образец моей AAAPage, так как другие имеют аналогичную структуру:
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);
});
};
}
начальное состояние.js:
export default {
AAAList: [],
BBBList: [],
CCCList: []
};
На данный момент я считаю, что предоставил достаточно информации для своего кода. Я следил за учебными пособиями при разработке этого хранилища избыточности, и я не уверен, почему, когда я перехожу от «/abc/xyz» к «/abc» и обратно, или когда я перехожу к «/abc/xyz» из «/abc», мой хранилища пусты, хотя я вызвал метод loadAAA() в своем index.js. Все остальные страницы также затронуты. Однако, когда я напрямую нажимаю «/abc/xyz», мои магазины подключаются, а раскрывающиеся списки заполняются. Что случилось? Это из-за моих методов жизненного цикла?
Я использую реакцию v15.6.2, redux v3.7.2 и redux-thunk v2.3.0.
Спасибо за руководство.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы вызываете loadAAA только на верхнем уровне index.js, который выполняется только один раз при загрузке вашей страницы. Если вы хотите отправлять его каждый раз, когда отображается ваша страница XYZPage, введите XYZ componentDidMount
@AKJ - @Andy Ray сказал это правильно, но я хотел бы добавить, что componentDidMount - это лучшее место для загрузки async вызовов, так как это вызывается после рендеринга, а о Store хранилище избыточности хранит данные, пока вы не обновите страницу после обновления хранилища избыточности. повторно инициализируется, если вам нужно сохранить данные после обновления, попробуйте редукс-сохраняется
Если это так, то предлагаем ли мы, чтобы mapStateToProps работал только для состояний, которые не являются асинхронными вызовами? Я всегда предполагал, что когда я делаю диспетчерский вызов, хранилище запоминает данные до тех пор, пока сеанс жив. Я не ожидал, что магазин забудет свое состояние, когда я перейду с одной страницы на другую. Как уже упоминалось, я следовал руководству Cory-house по множественному праву, и в этом руководстве он не использовал componentDidMount для вызова некоторых данных, полученных из фиктивного вызова синхронизации. Он просто увлажнил хранилище на index.js и передал его через <Provider>. Не могли бы вы просветить меня дальше?
React позволяет нам решить проблему несколькими способами. В вашем случае ваш магазин помнит или нет? вы можете проверить это, используя редукс-dev-инструменты, просто держите инструмент разработчика открытым и проверяйте при переходе с другой страницы.
Когда я открыл dev-tool redux, мой магазин все еще помнит состояние
Если ваш магазин помнит это, значит, вам нужно иметь дело с методом жизненного цикла для отображения экрана данных.
Могу я узнать, что это за метод жизненного цикла?
Хорошо, так и сделаю, но зачем это нужно? Разве хранилище избыточности не запоминает состояние, или я неправильно понимаю, как работает хранилище избыточности?