道具更新时重新渲染组件(使用 Redux)
Posted
技术标签:
【中文标题】道具更新时重新渲染组件(使用 Redux)【英文标题】:Re render Component when props updates (w/ Redux) 【发布时间】:2018-01-30 05:01:37 【问题描述】:好的,所以我有 2 个组件,地图和应用程序。 App 组件基本上保存了地图。
这是我的应用程序的代码:
import React, Component from 'react';
import Text, View from 'react-native';
import StackNavigator, TabNavigator from 'react-navigation';
//Redux
import Provider from 'react-redux';
import createStore, applyMiddleware from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
//Screen Imports
import CenterNew from './screens/CenterNew';
import Map from './components/Map';
import Profile from './containers/Profile';
import Review from './containers/Review';
import connect from 'react-redux';
var store = createStore(rootReducer, , applyMiddleware(thunk));
class App extends Component
render ()
console.ignoredYellowBox = ['Remote debugger'];
const MainScreenNavigator = TabNavigator(
Centers: screen: Map,
Review: screen: Review,
Profile: screen: Profile
);
MainScreenNavigator.navigationOptions =
title: this.props.map.title
;
const Screens = StackNavigator(
Home: screen: MainScreenNavigator,
CenterNew: screen: CenterNew
);
return (
<Provider store=store>
<Screens />
</Provider>
);
const connectWithStore = (store, WrappedComponent, mapStateToProps) =>
let ConnectedWrappedComponent = connect(mapStateToProps)(WrappedComponent);
return (props) =>
return <ConnectedWrappedComponent ...props store=store />
const mapStateToProps = (state) =>
return
map: state.map
;
;
App = connectWithStore(createStore(rootReducer, , applyMiddleware(thunk)), App, mapStateToProps);
export default App;
在 sn-p 中,我使用
MainScreenNavigator.navigationOptions =
title: this.props.map.title
;
因此,每当呈现 App 时,我都会记录初始状态,正如您在 componentWillMount()
中看到的那样,这就是结果。一个syou可以看到,初始标题是'Home'
现在,在我的地图中,我有一个按钮可以触发此操作创建者,只是为了更改标题文本:
this.props.changeHeaderTitle('Test');
console.log(this.props.map);
代码:
export const changeHeaderTitle = (title) =>
return
type: 'CHANGE_HEADER_TITLE',
payload: title
;
;
这是我的减速器:
const INITIAL_STATE =
isPinnable: false,
pinnedCoordinateLatitude: 0,
pinnedCoordinateLongitude: 0,
region:
latitude: 14.582524,
longitude: 121.061547,
latitudeDelta: 0.007,
longitudeDelta: 0.007
,
title: '',
searched: false
;
export default (state = INITIAL_STATE, action) =>
switch(action.type)
case 'ENABLE_PINNING':
return ... state, isPinnable: true
case 'DISABLE_PINNING':
return ... state, isPinnable: false,
pinnedCoordinateLatitude: action.payload.latitude,
pinnedCoordinateLongitude: action.payload.longitude
case 'GET_PINNED_COORDINATE':
let test = action.payload.longitude;
return
...state,
isPinnable: false,
pinnedCoordinateLatitude: action.payload.latitude,
pinnedCoordinateLongitude: action.payload.longitude
case 'GET_CURRENT_REGION':
return ...state, region: region
case 'CHANGE_CURRENT_REGION':
return ...state, region: action.payload
case 'CHANGE_HEADER_TITLE':
return ...state, title: action.payload
case 'SEARCHED_VIEW':
return ...state, searched: action.payload
default:
return state;
;
每当触发操作时,我都知道标题已更新,因为我记录了它,正如您在
中看到的那样this.props.changeHeaderTitle('Test');
console.log(this.props.map);
但在我看来,标题仍然是“主页”。我提到了这个:rerender react component when prop changes 并尝试使用componentWillRecieveProps()
,但是当从地图组件触发this.props.changeHeaderTitle('Test');
操作时它没有记录。
【问题讨论】:
展示你的减速器。如果状态正在改变,但你的组件没有更新,这通常是因为你改变了状态对象而不是返回一个新的对象。请参阅redux.js.org/docs/basics/Reducers.html -> “我们不会改变状态。我们使用 Object.assign() 创建一个副本” 我更新了我的帖子..我认为我没有改变状态,因为我使用了传播运算符?.. 【参考方案1】:您需要将 Redux 存储与组件连接起来。因此你应该添加这个sn-p:
mapStateToProps(store)
const title = store;
return title ;
export default connect(mapStateToProps, changeHeaderTitle )(App)
mapStateToProps 函数将订阅 redux 存储更新。每次你的状态改变时,你的组件都会自动重新渲染。您可以在此处找到有关将组件连接到 redux 存储的更多信息:react-redux api docs
【讨论】:
我已经更新了我的代码 sn-p 以包含我的完整代码.. 它已经订阅了 redux 我认为您忘记将动作创建者“changeHeaderTitle”注入到连接方法中,就像我在上面的示例中所做的那样。这就是为什么你的状态不会改变。 在 Map 组件中调用了“changeHeaderTitle”动作创建者。 App 组件仅通过道具接收“更新”“更新”状态.. 所以我认为我不需要注入 changeHeaderTitle() 动作创建者,因为我只在地图组件中使用它...【参考方案2】:您无法像在您提供的代码中那样更新屏幕标题。
//This is only needed if you want to set the title from another screen
static navigationOptions = ( navigation ) =>
const state = navigation;
return title: `$state.params.title`,
;
;
ChangeThisTitle = (titleText) =>
const setParams = this.props.navigation; setParams( title: titleText )
//Your render method
render()
//Views goes here
要更改标题,您可以从 onPress 调用更改标题方法。
您可以参考link了解更多详情。
【讨论】:
我正在嵌套导航器。所以我目前使用这个MainScreenNavigator.navigationOptions = title: 'My Chats', ;
来更改标题.. 我在这里得到它:reactnavigation.org/docs/intro/nesting以上是关于道具更新时重新渲染组件(使用 Redux)的主要内容,如果未能解决你的问题,请参考以下文章
高阶组件状态正在正确更新,但接收道具的包装组件不会在状态更改时重新渲染
当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件
React Native 和 Redux:为啥子组件不会在每次状态更新时重新渲染?