我想在按下其中一个特殊 child 时更改多个 child 的背景
I want to change background of a more than one child on press of one of the special child
你好,我刚开始学习react native,一直卡在这。我不确定这是正确的做法还是需要改变。请帮忙。
我有一个 parent 组件和一个 child 组件。 Parent 包含平面列表和渲染 child。如果一个child很特别那么想改变多个child的背景,如果不是那么只有他的背景会改变。
class Parent extends Component {
constructor(props){
a = ['a','h','n','1','2','3'];
this.state={
list=a,
};
}
render(){
return (
<View>
<FlatList
data={this.state.list}
renderItem={(item) => (
<Child name={item['item']} />)} />
</View>
)
}
}
class Child extends Component {
constructor(props){
this.state={
itemState:"off"
}
pressed(name){
//if name is alpha it's special change background of multiple.
//else change background of this only.
}
getImage(){
if(this.state.itemState === "on){
return require('onImgPath')
else
return require('offImgPath')
}
render(){
var imgp=this.getImage();
return (
<TouchableOpacity onPress={this.pressed.bind(this,this.props.name)>
<ImageBackground source={imgp}>
<Text>{this.props.name}</Text>
</ImageBackground>
</TouchableOpacity>
)
}
}
按下平面列表项目即 child 我想更改图像。这将基于 child 的名称,如果其 'a' 那么所有非特殊 child 将背景更改为 'on'。如果 'h' 那么只有前半部分会变成 'on' 而其他部分会变成 'off' 如果它是 'n' 那么所有非特殊的都会变成关闭图像。
请告知如何使它工作以及哪种方式应该适合处理这种情况。
你应该精确:
如果名字是alpha它是multiple的特殊变化背景
更正
这是对您的代码的可能更正:
import React, { Component } from 'react';
import { StyleSheet, View, FlatList, Text, ImageBackground,TouchableOpacity } from 'react-native';
export default class Parent extends Component {
constructor(props){
super(props);
let a = ['a','h','n','1','2','3'];
this.state={
list:a,
};
}
_renderItem = ({ item, index }) => (<Child name={item} /> );
render(){
return (
<View style={styles.container}>
<FlatList
data={this.state.list}
renderItem= {this._renderItem}/>
</View>
)
}
}
class Child extends Component {
constructor(props){
super(props);
this.state={
itemState:true,
}
}
pressed = () => {
if(this.props.name === 'alpha'){
// Do stuffs
}
this.setState({itemState:!this.state.itemState});
console.log(this.props.name);
}
render(){
return (
<TouchableOpacity style={styles.container} onPress={()=>this.pressed()} style={{ width: '100%', height: 80 }}>
<ImageBackground source={this.state.itemState === true ? require('assets/on.png') : require('assets/off.png')} style={styles.image}>
<Text style={styles.text}>{this.props.name}</Text>
</ImageBackground>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
text : {
fontSize:16,
marginLeft:20,
color:'white'
},
image : { width: '100%', height: '100%' }
})
开始屏幕
单击了 'n' 和“2”
结论
- 你必须在构造函数中调用'super'
- 注意关闭所有打开的括号:{}
- 看看你的代码有什么不同,学习和享受吧!
更准确的答案
如果我查看此线程标题中的问题,一种解决方案是在 parent 组件中控制 children 的状态。在这种情况下,您必须考虑 children 的行为。
这是一个解决方案:
import React, { Component } from 'react';
import { StyleSheet, View, FlatList, Text, ImageBackground,TouchableOpacity } from 'react-native';
let a = [
{name :'a',itemState: true,linked:['n','1']},
{name :'h',itemState: true},
{name :'n',itemState: true},
{name :'1',itemState: true},
{name :'2',itemState: true,linked:['h']},
{name :'3',itemState: true}
];
export default class Parent extends Component {
constructor(props){
//Never forget to call super()
super(props);
this.state={
list:a,
listLinked : []
};
}
//Don't forget to pass the callBack function
//This callBack process the state of items in list
_renderItem = ({ item, index }) => (<Child item={item} callBack={this._callBack}/> );
_callBack = (entrie) => {
//Look if item has linked elements and do the job
if (undefined != entrie.item.linked){
for(var i=0; i< entrie.item.linked.length; i++){
var indexLinkedItem = a.findIndex(element => element.name===entrie.item.linked[i]);
//Here you must think to the behaviour of your function
//By default, I toggle the actuel state of the linked item
//If you want to force them to be true or false
//You have to write :
// a[indexLinkedItem].itemState = true
//or
// a[indexLinkedItem].itemState = false
a[indexLinkedItem].itemState = !a[indexLinkedItem].itemState;
}
}
//In all case, the state of the pressed item change
var indexItem = a.findIndex(element => element.name===entrie.item.name);
a[indexItem].itemState = !a[indexItem].itemState;
//Assign the new list a to the state
this.setState({list : a});
}
render(){
console.log('main');
return (
<View style={styles.container}>
<FlatList
data={this.state.list}
renderItem= {this._renderItem}
//Use extraData to be sure flatlist rerender after _callBack
extraData={this.state}/>
</View>
)
}
}
class Child extends Component {
//This is a stateless component
pressed = () => {
this.props.callBack(this.props);
}
render(){
return (
<TouchableOpacity style={styles.container} onPress={()=>this.pressed()} style={{ width: '100%', height: 80 }}>
<ImageBackground source={this.props.item.itemState === true ? require('assets/on.png') : require('assets/off.png')} style={styles.image}>
<Text style={styles.text}>{this.props.item.name}</Text>
</ImageBackground>
</TouchableOpacity>
)
}
}
//This is the style you can change
//ImageBackground must have size
const styles = StyleSheet.create({
container: {
flex: 1,
},
text : {
fontSize:16,
marginLeft:20,
color:'white'
},
image : { width: '100%', height: '100%' }
})
在开始屏幕上,当我单击第一个项目 'a' 时,链接项目 'n' 和“1”的状态也会发生变化:
结论
你想我现在点'n'会怎么样?
它只改变'n'的状态还是'a'、'n'和'1'的状态?
如果您有另一个项目与 'a'、'n' 或 '1' 链接会怎样?
在此处观看实际代码:
https://www.youtube.com/watch?v=tmsfhZ53zNE&feature=youtu.be
你好,我刚开始学习react native,一直卡在这。我不确定这是正确的做法还是需要改变。请帮忙。
我有一个 parent 组件和一个 child 组件。 Parent 包含平面列表和渲染 child。如果一个child很特别那么想改变多个child的背景,如果不是那么只有他的背景会改变。
class Parent extends Component {
constructor(props){
a = ['a','h','n','1','2','3'];
this.state={
list=a,
};
}
render(){
return (
<View>
<FlatList
data={this.state.list}
renderItem={(item) => (
<Child name={item['item']} />)} />
</View>
)
}
}
class Child extends Component {
constructor(props){
this.state={
itemState:"off"
}
pressed(name){
//if name is alpha it's special change background of multiple.
//else change background of this only.
}
getImage(){
if(this.state.itemState === "on){
return require('onImgPath')
else
return require('offImgPath')
}
render(){
var imgp=this.getImage();
return (
<TouchableOpacity onPress={this.pressed.bind(this,this.props.name)>
<ImageBackground source={imgp}>
<Text>{this.props.name}</Text>
</ImageBackground>
</TouchableOpacity>
)
}
}
按下平面列表项目即 child 我想更改图像。这将基于 child 的名称,如果其 'a' 那么所有非特殊 child 将背景更改为 'on'。如果 'h' 那么只有前半部分会变成 'on' 而其他部分会变成 'off' 如果它是 'n' 那么所有非特殊的都会变成关闭图像。
请告知如何使它工作以及哪种方式应该适合处理这种情况。
你应该精确:
如果名字是alpha它是multiple的特殊变化背景
更正
这是对您的代码的可能更正:
import React, { Component } from 'react';
import { StyleSheet, View, FlatList, Text, ImageBackground,TouchableOpacity } from 'react-native';
export default class Parent extends Component {
constructor(props){
super(props);
let a = ['a','h','n','1','2','3'];
this.state={
list:a,
};
}
_renderItem = ({ item, index }) => (<Child name={item} /> );
render(){
return (
<View style={styles.container}>
<FlatList
data={this.state.list}
renderItem= {this._renderItem}/>
</View>
)
}
}
class Child extends Component {
constructor(props){
super(props);
this.state={
itemState:true,
}
}
pressed = () => {
if(this.props.name === 'alpha'){
// Do stuffs
}
this.setState({itemState:!this.state.itemState});
console.log(this.props.name);
}
render(){
return (
<TouchableOpacity style={styles.container} onPress={()=>this.pressed()} style={{ width: '100%', height: 80 }}>
<ImageBackground source={this.state.itemState === true ? require('assets/on.png') : require('assets/off.png')} style={styles.image}>
<Text style={styles.text}>{this.props.name}</Text>
</ImageBackground>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
text : {
fontSize:16,
marginLeft:20,
color:'white'
},
image : { width: '100%', height: '100%' }
})
开始屏幕
单击了 'n' 和“2”
结论
- 你必须在构造函数中调用'super'
- 注意关闭所有打开的括号:{}
- 看看你的代码有什么不同,学习和享受吧!
更准确的答案
如果我查看此线程标题中的问题,一种解决方案是在 parent 组件中控制 children 的状态。在这种情况下,您必须考虑 children 的行为。
这是一个解决方案:
import React, { Component } from 'react';
import { StyleSheet, View, FlatList, Text, ImageBackground,TouchableOpacity } from 'react-native';
let a = [
{name :'a',itemState: true,linked:['n','1']},
{name :'h',itemState: true},
{name :'n',itemState: true},
{name :'1',itemState: true},
{name :'2',itemState: true,linked:['h']},
{name :'3',itemState: true}
];
export default class Parent extends Component {
constructor(props){
//Never forget to call super()
super(props);
this.state={
list:a,
listLinked : []
};
}
//Don't forget to pass the callBack function
//This callBack process the state of items in list
_renderItem = ({ item, index }) => (<Child item={item} callBack={this._callBack}/> );
_callBack = (entrie) => {
//Look if item has linked elements and do the job
if (undefined != entrie.item.linked){
for(var i=0; i< entrie.item.linked.length; i++){
var indexLinkedItem = a.findIndex(element => element.name===entrie.item.linked[i]);
//Here you must think to the behaviour of your function
//By default, I toggle the actuel state of the linked item
//If you want to force them to be true or false
//You have to write :
// a[indexLinkedItem].itemState = true
//or
// a[indexLinkedItem].itemState = false
a[indexLinkedItem].itemState = !a[indexLinkedItem].itemState;
}
}
//In all case, the state of the pressed item change
var indexItem = a.findIndex(element => element.name===entrie.item.name);
a[indexItem].itemState = !a[indexItem].itemState;
//Assign the new list a to the state
this.setState({list : a});
}
render(){
console.log('main');
return (
<View style={styles.container}>
<FlatList
data={this.state.list}
renderItem= {this._renderItem}
//Use extraData to be sure flatlist rerender after _callBack
extraData={this.state}/>
</View>
)
}
}
class Child extends Component {
//This is a stateless component
pressed = () => {
this.props.callBack(this.props);
}
render(){
return (
<TouchableOpacity style={styles.container} onPress={()=>this.pressed()} style={{ width: '100%', height: 80 }}>
<ImageBackground source={this.props.item.itemState === true ? require('assets/on.png') : require('assets/off.png')} style={styles.image}>
<Text style={styles.text}>{this.props.item.name}</Text>
</ImageBackground>
</TouchableOpacity>
)
}
}
//This is the style you can change
//ImageBackground must have size
const styles = StyleSheet.create({
container: {
flex: 1,
},
text : {
fontSize:16,
marginLeft:20,
color:'white'
},
image : { width: '100%', height: '100%' }
})
在开始屏幕上,当我单击第一个项目 'a' 时,链接项目 'n' 和“1”的状态也会发生变化:
结论
你想我现在点'n'会怎么样? 它只改变'n'的状态还是'a'、'n'和'1'的状态? 如果您有另一个项目与 'a'、'n' 或 '1' 链接会怎样?
在此处观看实际代码:
https://www.youtube.com/watch?v=tmsfhZ53zNE&feature=youtu.be