使用 react / redux / react-native-router-flex 在另一个场景中更改状态后刷新概览场景
Refresh overview scene after changing state in another scene with react / redux / react-native-router-flex
github中提供的最简化的工作示例!!!
我有一个简单的应用程序来学习使用 React Native 和 Redux 构建应用程序。据我了解,如果您在 render 方法中显示来自 redux 状态的数据,然后更改此状态的值,那么该值也会更改,并且 react 重新渲染所有由于状态更改而需要重新渲染的组件。
我在 github 上有可用的应用程序:https://github.com/schingeldi/checklist
真的很简单。我有一个概览,如果你点击一个条目的状态,你会进入一个详细的页面。如果您单击 "Mark xxx",redux 状态中的状态已更改(根据日志),但在概览场景中未刷新。
基本上我有一个 Overview.js:
class Overview extends Component {
constructor(props) {
super(props);
this.state = {fetching:false};
}
entries() {
// console.log("Overview");
// console.log(this.props);
// console.log(this.props.entries);
return Object.keys(this.props.entries).map(key => this.props.entries[key]);
}
componentDidMount() {
this.setState({fetching:true});
this.props.actions.getEntries()
.then( (res) => {
this.setState({fetching: false});
})
}
handleChange(entryId) {
Actions.detail({id: entryId});
}
render() {
return (
<View>
<ScrollView>
{ !this.state.fetching && this.entries().map((entry) => {
return (
<TouchableHighlight key={entry.id}>
<View >
<Text>{entry.name}</Text>
<TouchableHighlight onPress={(entryId ) => this.handleChange(entry.id)}><Text>{entry.status}</Text></TouchableHighlight>
<Text>---------------------------</Text>
</View>
</TouchableHighlight>
)
}
)
}
{this.state.fetching ? <Text>Searching </Text> : null }
</ScrollView>
</View>
)}
}
function mapStateToProps(state) {
return {entries: state.default.entries };
}
function mapDispatchToProps(dispatch) {
return {actions: bindActionCreators(actions,dispatch)};
}
export default connect(mapStateToProps, mapDispatchToProps)(Overview);
当点击状态 ({entry.status}) 我打开另一个场景 Details.js:
class Detail extends Component {
constructor(props) {
super(props);
this.state = {}
}
componentWillMount() {
this.setState({
entry: this.props.entries[this.props.id]
})
}
patchEntry(newStatus) {
console.log("Details: patchEntry with " + this.props.id +" and " + newStatus );
this.props.actions.patchEntry(this.props.id, newStatus);
}
render() {
return (
<View>
<Text>{this.state.entry.name}</Text>
<TouchableHighlight onPress={() => this.patchEntry('done')}><Text>Mark done</Text></TouchableHighlight>
<TouchableHighlight onPress={() => this.patchEntry('cancelled')}><Text>Mark cancelled</Text></TouchableHighlight>
</View>
)
}
}
function mapStateToProps(state) {
console.log(state);
return {entries: state.default.entries };
}
function mapDispatchToProps(dispatch) {
return {actions: bindActionCreators(actions,dispatch)};
}
export default connect( mapStateToProps, mapDispatchToProps)(Detail);
我有一个动作和一个减速器,当按下其中一个 TouchableHighlights 时,它们被称为非常好。我什至在日志中看到输出整个状态时状态发生了变化
但我的问题是,一旦我从详细场景返回(pop),如何在概览场景中刷新状态?
如果您需要更多信息,请告诉我,但重现应该很简单,因为我编写了一个完整的工作应用程序。只需克隆、npm 安装和 运行 它。
非常感谢您的帮助。
我快速查看了您的代码,这里有一些 suggestions/information。
在您的 Detail.js
文件中,您将设置安装组件后的状态。
当你更新你的 redux store 并获得刷新的道具时,它不会更新你的 UI 因为它反映了你的状态,你的状态不会获得新值因为你只将它设置为 componentWillMount
方法。查看更多信息 here in the docs.
另外你好像不太清楚什么时候使用React组件的state。
在这个例子中,从 Detail.js
文件你根本不需要组件的状态。您可以直接从属性计算该值。
例如:
render() {
const entry = this.props.entries[this.props.id];
return (
<View>
<Text>{entry.name}</Text>
<TouchableHighlight onPress={() => this.patchEntry('done')}><Text>Mark done</Text></TouchableHighlight>
<TouchableHighlight onPress={() => this.patchEntry('cancelled')}><Text>Mark cancelled</Text></TouchableHighlight>
</View>
)
}
您甚至可以在 mapStateToProps
函数中执行此操作。更多信息 here.
例如:
function mapStateToProps(state, ownProps) {
return {
entries: state.default.entries,
entry: state.default.entries[ownProps.id],
};
}
关于正在更新的 UI,您的 Overview.js
文件似乎没问题,因为它的渲染方法反映了 props
而不是它的状态。
更新 06/27
我刚刚查看了您的 reducers
,您可能还需要进行一些修复。
case ENTRY_PATCHING:
let patchedEntries = state.entries;
patchedEntries[action.data.entryId].status = action.data.newStatus;
return {...state,
entries: patchedEntries
}
在这个减速器中,你正在改变你的状态,你不能那样做。 redux store 不能改变。您可以在此处查看更多详细信息 http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html
所以,修复示例:
case ENTRY_PATCHING:
const patchedEntry = {
...state.entries[action.data.entryId],
status: action.data.newStatus
}
return {
...state,
entries: {
...state.entries,
[action.data.entryId]: patchedEntry,
}
}
github中提供的最简化的工作示例!!!
我有一个简单的应用程序来学习使用 React Native 和 Redux 构建应用程序。据我了解,如果您在 render 方法中显示来自 redux 状态的数据,然后更改此状态的值,那么该值也会更改,并且 react 重新渲染所有由于状态更改而需要重新渲染的组件。
我在 github 上有可用的应用程序:https://github.com/schingeldi/checklist
真的很简单。我有一个概览,如果你点击一个条目的状态,你会进入一个详细的页面。如果您单击 "Mark xxx",redux 状态中的状态已更改(根据日志),但在概览场景中未刷新。
基本上我有一个 Overview.js:
class Overview extends Component {
constructor(props) {
super(props);
this.state = {fetching:false};
}
entries() {
// console.log("Overview");
// console.log(this.props);
// console.log(this.props.entries);
return Object.keys(this.props.entries).map(key => this.props.entries[key]);
}
componentDidMount() {
this.setState({fetching:true});
this.props.actions.getEntries()
.then( (res) => {
this.setState({fetching: false});
})
}
handleChange(entryId) {
Actions.detail({id: entryId});
}
render() {
return (
<View>
<ScrollView>
{ !this.state.fetching && this.entries().map((entry) => {
return (
<TouchableHighlight key={entry.id}>
<View >
<Text>{entry.name}</Text>
<TouchableHighlight onPress={(entryId ) => this.handleChange(entry.id)}><Text>{entry.status}</Text></TouchableHighlight>
<Text>---------------------------</Text>
</View>
</TouchableHighlight>
)
}
)
}
{this.state.fetching ? <Text>Searching </Text> : null }
</ScrollView>
</View>
)}
}
function mapStateToProps(state) {
return {entries: state.default.entries };
}
function mapDispatchToProps(dispatch) {
return {actions: bindActionCreators(actions,dispatch)};
}
export default connect(mapStateToProps, mapDispatchToProps)(Overview);
当点击状态 ({entry.status}) 我打开另一个场景 Details.js:
class Detail extends Component {
constructor(props) {
super(props);
this.state = {}
}
componentWillMount() {
this.setState({
entry: this.props.entries[this.props.id]
})
}
patchEntry(newStatus) {
console.log("Details: patchEntry with " + this.props.id +" and " + newStatus );
this.props.actions.patchEntry(this.props.id, newStatus);
}
render() {
return (
<View>
<Text>{this.state.entry.name}</Text>
<TouchableHighlight onPress={() => this.patchEntry('done')}><Text>Mark done</Text></TouchableHighlight>
<TouchableHighlight onPress={() => this.patchEntry('cancelled')}><Text>Mark cancelled</Text></TouchableHighlight>
</View>
)
}
}
function mapStateToProps(state) {
console.log(state);
return {entries: state.default.entries };
}
function mapDispatchToProps(dispatch) {
return {actions: bindActionCreators(actions,dispatch)};
}
export default connect( mapStateToProps, mapDispatchToProps)(Detail);
我有一个动作和一个减速器,当按下其中一个 TouchableHighlights 时,它们被称为非常好。我什至在日志中看到输出整个状态时状态发生了变化
但我的问题是,一旦我从详细场景返回(pop),如何在概览场景中刷新状态?
如果您需要更多信息,请告诉我,但重现应该很简单,因为我编写了一个完整的工作应用程序。只需克隆、npm 安装和 运行 它。
非常感谢您的帮助。
我快速查看了您的代码,这里有一些 suggestions/information。
在您的 Detail.js
文件中,您将设置安装组件后的状态。
当你更新你的 redux store 并获得刷新的道具时,它不会更新你的 UI 因为它反映了你的状态,你的状态不会获得新值因为你只将它设置为 componentWillMount
方法。查看更多信息 here in the docs.
另外你好像不太清楚什么时候使用React组件的state。
在这个例子中,从 Detail.js
文件你根本不需要组件的状态。您可以直接从属性计算该值。
例如:
render() {
const entry = this.props.entries[this.props.id];
return (
<View>
<Text>{entry.name}</Text>
<TouchableHighlight onPress={() => this.patchEntry('done')}><Text>Mark done</Text></TouchableHighlight>
<TouchableHighlight onPress={() => this.patchEntry('cancelled')}><Text>Mark cancelled</Text></TouchableHighlight>
</View>
)
}
您甚至可以在 mapStateToProps
函数中执行此操作。更多信息 here.
例如:
function mapStateToProps(state, ownProps) {
return {
entries: state.default.entries,
entry: state.default.entries[ownProps.id],
};
}
关于正在更新的 UI,您的 Overview.js
文件似乎没问题,因为它的渲染方法反映了 props
而不是它的状态。
更新 06/27
我刚刚查看了您的 reducers
,您可能还需要进行一些修复。
case ENTRY_PATCHING:
let patchedEntries = state.entries;
patchedEntries[action.data.entryId].status = action.data.newStatus;
return {...state,
entries: patchedEntries
}
在这个减速器中,你正在改变你的状态,你不能那样做。 redux store 不能改变。您可以在此处查看更多详细信息 http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html
所以,修复示例:
case ENTRY_PATCHING:
const patchedEntry = {
...state.entries[action.data.entryId],
status: action.data.newStatus
}
return {
...state,
entries: {
...state.entries,
[action.data.entryId]: patchedEntry,
}
}