更新:我最终只是从部分列表切换到滚动视图,并且状态正确更新。我不了解Pure Component,这就是它没有重新渲染的原因。
我对原生反应非常陌生,我正在使用redux之类解决很多问题。但是,我似乎无法理解为什么状态更改时我的组件没有更新。我不确定需要多少信息,所以我将尝试在应关注的代码中添加注释。
复选框是通过api调用动态呈现的。然后,我使用该数据创建一个具有true / false值的项目列表,以将其传递给复选框。列表中的键专门与每个复选框相关联。我试图将其保持尽可能的动态,以允许后端的数据更改。当按下复选框时,CHECK调度将触发并按预期更新状态,但是不会更新该复选框以反映该状态。打印清单的状态表明状态正在正确更新。 Redux可以正常工作,但是复选框的选中状态没有改变。
最大的问题是:为什么该复选框未使用新状态更新?
先谢谢了。
我的代码如下:
Details.js(容器)
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { actionCreators } from '../redux/actionCreators'
import DetailsScreen from '../components/DetailsScreen';
class Details extends Component {
componentDidMount() {
const { getRouteList } = this.props
getRouteList()
}
render() {
const { listReady, routeList, checkedList, check } = this.props
return (
<DetailsScreen
sections={routeList}
listReady={listReady}
checkedList={checkedList} //passing list of items with true/false values to DetailsScreen
check={check} //function that calls an actionCreators(dispatch) below **this works**
/>
)
}
}
const mapStateToProps = (state) => ({
listReady: state.listReady,
routeList: state.routeList,
checkedList: state.checkedList //list of items that correlate with the checked state of the checkboxes, e.g. state.checkedList[0] = Item1: true
})
const mapDispatchToProps = (dispatch) => ({
getRouteList: () => {
dispatch(actionCreators.getRouteList())
},
check: key => {
dispatch(actionCreators.check(key))
}
})
export default connect(mapStateToProps, mapDispatchToProps)(Details)
DetailsScreen.js(组件)
import React, { Component } from 'react'
import { View, Text, SectionList, StyleSheet } from 'react-native'
import { Button, CheckBox } from 'react-native-elements'
import { connect } from 'react-redux'
import { actionCreators } from '../redux/actionCreators'
const extractKey = ({ id }) => id
class DetailsScreen extends Component {
renderItem = ({ item }) => {
const {checkedList, check} = this.props
return (
<CheckBox
title={item.Description}
checked={checkedList[item.Description]} //getting the state of the checkbox from checkedList **this works, initially shows up correctly, but does not get updated**
checkedIcon='plus-square'
checkedColor='blue'
uncheckedIcon='minus-circle'
uncheckedColor='red'
onPress={() => check(item.Description)} //action creator helper that switches the state of the item (true/false)
/>
)
}
renderSectionHeader = ({ section }) => {
return (
<Text style={styles.header}>
{section.title}
</Text>
)
}
render() {
const { sections, listReady } = this.props
if (listReady) {
return (
<SectionList
style={styles.container}
sections={sections}
renderItem={this.renderItem}
renderSectionHeader={this.renderSectionHeader}
keyExtractor={extractKey}
/>
)
}
return (
<View>
<Text>Loading...</Text>
</View>
)
}
}
const styles = *styles for stuff above*
export default DetailsScreen
actionCreators.js
import * as types from './actionTypes'
import { AsyncStorage } from "react-native"
export const actionCreators = {
check: key => {
return {
type: types.CHECK,
payload: key //item.Description from the checkbox
}
},
getRouteList: () => {
return {
type: types.GET_ROUTE_LIST,
payload:
fetch(url)
.then(result => result.json()) //result is formed for a React Native SectionList
.catch(() => [])
}
}
*other actions*
}
reducer.js
import * as types from './actionTypes'
export const initialState = {
routeList: [],
checkedList: {},
listReady: false,
}
export const reducer = (state = initialState, action) => {
const { type, payload } = action
switch (type) {
case types.CHECK:
console.log(state.checkedList) //shows that the state IS indeed being updated, but it is not changing on the checkbox
return {
...state,
checkedList: {...state.checkedList, [payload]: !state.checkedList[payload]}
}
case types.GET_ROUTE_LIST_FULFILLED:
list = {}
payload[0].data.map((item) => { //
if (item.Description == "Route 1") { //test to make sure that that the checkboxes were initially getting set correctly
list[item.Description] = true
}
else list[item.Description] = false
})
return {
...state,
routeList: payload, //checkboxes are rendered with this
listReady: true,
checkedList: list //this holds the state of the checkedness of the checkboxes **updated in CHECK reducer**
}
default:
return state
}
}
答案 0 :(得分:0)
我不是本地反应专家,但问题与“正常反应”有关。
未成年人:key
中有一个<CheckBox >
属性-在index
中使用renderItem
参数
更成问题的是数据结构/参数传递。 SectionList
是pureComponent
-由于性能原因,使用浅等于-在数据不变时不会重新呈现。但是,即使它是正常的组件也无法使用;)-SectionList
会获得不变的道具-sections
(sections={routeList}
)。
routeList
未更新,则不重新渲染SectionList
。 SectionList
不知道项目(<CheckBox >
)使用checkedList
。
checkedList
与sections
(标记选中的部分/项目)组合(在渲染中)以创建作为“部分”传递的新sectionsChecked
数组。每次对render的调用都会创建一个新数组,强制刷新SectionList
。mapStateToPorps
。SectionList
感觉到它获取了新数据-传递新的引用是绝对的。使用任何您喜欢的方法传递sections
的副本,这会导致新的对象/数组。第3种方法可能不够好,因为renderItem应该提供数据作为道具(在每个部分中都进行了“检查”)-pureComponent刷新问题-它不应是深层对象属性/派生数据。
所有内容都在文档中进行了描述。