this.setState 的正确写法

本文详细介绍了ReactNative中this.setState的不同使用方法,包括直接更新状态、使用回调函数、动态添加状态变量等,并对比了与微信小程序setData的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React Native 的 this.setState 同微信小程序的 this.setData 很类似,但是呢,写法却不一样,注意别混淆了
最简单的写法 —— 写法六
同小程序一致的写法 —— 写法五

setState 函数是异步执行的函数

写法一

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    View,
    Text,
    TextInput,
    PixelRatio,
} from 'react-native';

const instructions = Platform.select({
    ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
    android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
            inputedNum: '',//写法1
        };
    }

    updateNum(newText) {//写法1
        this.setState((state) => {
            return {
                inputedNum: newText
            };
        });
    }

    render() {

        return (
            <View style={styles.container}>
                {/*写法1*/}
                <TextInput placeholder={'请输入账号'} onChangeText={(newText) => this.updateNum(newText)}/>
                <Text>您输入的手机号:{this.state.inputedNum}</Text>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    }
});

写法二

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    View,
    Text,
    TextInput,
    PixelRatio,
} from 'react-native';

const instructions = Platform.select({
    ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
    android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
            inputedPW: ''//写法2
        };
        this.updatePW = this.updatePW.bind(this);//写法2
    }

    updatePW(newText) {//写法2
        this.setState(() => {
            return {
                inputedPW: newText
            };
        });
    }

    render() {

        return (
            <View style={styles.container}>
                {/*写法2*/}
                <TextInput placeholder={'请输入密码'} secureTextEntry={true} onChangeText={this.updatePW}/>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    }
});

上述2种写法,请根据 写法1 或 写法2 的几处注意点,查看写法

setState 函数的原型

setState(oldState, callback)

如下例

updateNum(newText) {
        this.setState((oldState) => {
            //可以查看下oldState有哪些值
            for (let index in oldState) {
                console.log("index = ", index);
                console.log("value = ", oldState[index]);
            }
            return {
                inputedNum: newText,
                addedParam: 'I\'m a new added variable'
            }
        }, this.changeNumDone);
    }
    //自定义回调
    changeNumDone() {
        console.log('React Native has changed inputed Num,and has added a new variable');
    }

注意到上例中的 addedParam 了么

return {
  inputedNum: newText,
  addedParam: 'I\'m a new added variable'
}

这样动态的新增 state 变量,而不必在 this.state 里初始化,React Native 允许这种写法,但个人建议,最好把用到的变量提到 this.state 中,方便维护该组建中用到的变量管理,免得在维护时需要修改,漏掉某些变量

写法三

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    View,
    Text,
    TextInput,
    PixelRatio,
} from 'react-native';

const instructions = Platform.select({
    ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
    android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
            inputedNum: '',//写法3
        };
    }

    updateNum(inputedNum) {//写法3
        this.setState(() => {
            return {inputedNum};
        });
    }

    render() {

        return (
            <View style={styles.container}>
                {/*写法3*/}
                <TextInput placeholder={'请输入账号'} onChangeText={(newText) => this.updateNum(newText)}/>
                <Text>您输入的手机号:{this.state.inputedNum}</Text>
                <Text>您输入的手机号的长度:{this.state.inputedNum.length}</Text>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    }
});

写法四

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    View,
    Text,
    TextInput,
    PixelRatio,
} from 'react-native';

const instructions = Platform.select({
    ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
    android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
            inputedNum: '',//写法4
        };
    }

    updateNum(inputedNum) {//写法4
        this.setState({inputedNum});
    }

    render() {

        return (
            <View style={styles.container}>
                {/*写法4*/}
                <TextInput placeholder={'请输入账号'} onChangeText={(newText) => this.updateNum(newText)}/>
                <Text>您输入的手机号:{this.state.inputedNum}</Text>
                <Text>您输入的手机号的长度:{this.state.inputedNum.length}</Text>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    }
});

写法五(这个写法同微信小程序一致)

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    View,
    Text,
    TextInput,
    PixelRatio,
} from 'react-native';

const instructions = Platform.select({
    ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
    android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
            inputedNum: '',//写法4
        };
    }

    updateNum(inputedNum) {//写法4
        this.setState({
          inputedNum: inputedNum
        });
    }

    render() {

        return (
            <View style={styles.container}>
                {/*写法4*/}
                <TextInput placeholder={'请输入账号'} onChangeText={(newText) => this.updateNum(newText)}/>
                <Text>您输入的手机号:{this.state.inputedNum}</Text>
                <Text>您输入的手机号的长度:{this.state.inputedNum.length}</Text>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    }
});

写法六

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    View,
    Text,
    TextInput,
    PixelRatio,
} from 'react-native';

const instructions = Platform.select({
    ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
    android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
            inputedNum: '',//写法5
        };
    }

    render() {

        return (
            <View style={styles.container}>
                {/*写法5*/}
                <TextInput placeholder={'请输入账号'} onChangeText={(inputedNum) => this.setState({inputedNum})}/>
                <Text>您输入的手机号:{this.state.inputedNum}</Text>
                <Text>您输入的手机号的长度:{this.state.inputedNum.length}</Text>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    }
});
import React from 'react'; import { DeviceEventEmitter, TextInput, View, ScrollView, TouchableOpacity, Alert, StyleSheet, Dimensions, InteractionManager, KeyboardAvoidingView, Keyboard } from 'react-native'; import { FormValidationMessage, Header,CheckBox,Input,Text } from 'react-native-elements'; import { WhiteSpace, WingBlank,Button, InputItem,Tag, Flex,Picker,List,DatePicker,PickerView, Toast, Provider, Icon, Card,Modal } from '@ant-design/react-native'; import { HTTPPOST,HTTPGET,HTTPGET2,HTTPPOST2 } from '../../api/HttpRequest'; import MultiSelect from './MultiSelect' import { Table, TableWrapper, Row, Rows, Col, Cols, Cell } from 'react-native-table-component'; import ModalDropdown from 'react-native-modal-dropdown'; import { StackActions, NavigationActions } from 'react-navigation' import { connect } from 'react-redux'; const SCREEN_WIDTH = Dimensions.get('window').width; const SCREEN_HEIGHT = Dimensions.get('window').height; class PickingInStorage extends React.Component { constructor(props) { super(props); this.state = { times:null, queryTime:null, momToken:'', loading:false, qrcode:'', rkNum:'', tableHead: ['时间','条码', '重量', '操作人'], tableData: [ ['P1', 'A,B', '浙A12345,浙A12345,浙A12345'], ['P2', 'A,B,C', '浙A12345'] ], widthArr: [100, 45,45, 100], flexArr:[3,3,2,2], showCarInfo:[ // ['1','2','3','4'], // ['1','2','3','4'], // ['1','2','3','4'], ], } } //在渲染前调用,在客户端也在服务端 UNSAFE_componentWillMount() { } componentWillUnmount() { } componentDidMount() { // this.getMomToken(); this.state.times = new Date(); this.setState({times:new Date()}); this.onChangeDate(this.state.times); } gohome() { const { navigate } = this.props.navigation; navigate('Index'); } scanRkNum(){ let _this = this; const { navigate } = this.props.navigation; navigate('ScannerCode', { callback: (backData) => { let rkNum = backData; _this.setState({rkNum:rkNum}); } }) } scanQrcode() { let _this = this; const { navigate } = this.props.navigation; navigate('ScannerCode', { callback: (backData) => { let mt = backData; console.log('唛头',mt); _this.state.qrcode=mt; _this.setState({qrcode:mt}); this.getRkLogList(); } }) } onClose = () => { this.setState({ visible: false, }) } onChangeDate= value => { this.setState({times:value}); let tm=value; let mon = tm.getMonth()+1; let day = tm.getDate(); let yearStr = tm.getFullYear()+'-'; let monStr = mon<10?'0'+mon+'-':mon+'-'; let dayStr = day<10?'0'+day:day; let str=yearStr+monStr+dayStr; console.log('str',str) this.state.queryTime = str; this.setState({queryTime:str}); this.getRkLogList(); }; getRkLogList(){ var _this = this; let { status, user, token } = this.props; var key = Toast.loading('正在加载'); let params={ param:this.state.queryTime } let result = HTTPPOST('/yl/listYlJlRk',params, token) .then((res) => { Toast.remove(key); console.log('getRkLogList',res); if (res.code >0) { if(res.list){ let list = []; res.list.map(item=>{ console.log('item',item); list.push([item.createDate,item.qrcode,item.rkNum,item.name]); }) _this.setState({showCarInfo:list}); } console.log('getRkLogList',res.data); } else { Alert.alert('提示', '获取入库日志失败!'+res.msg); } }).catch((error) => { Alert.alert('提示', '获取入库日志异常!'+error); console.log('error', error); }) } //校验得到MOM token addYlJlRk() { console.log("开始校验", token); this.setState({loading:true}) var _this = this; let { status, user, token } = this.props; var data = { qrcode:this.state.qrcode, rkNum:this.state.rkNum }; HTTPPOST("/yl/addYlJlRk",data,token)//,'38d8a3329fe4e3a5f4c97fdf78f61dd2') .then((res) => { _this.setState({loading:false}) console.log('addYlJlRk',res); if (res.code>0) { // Alert.alert('提示',res.msg) _this.getRkLogList(); } else { Alert.alert('提示',res.msg) // _this.errorMsg = res.data.msg; // _this.isError = true; } }) .catch((error) => { _this.setState({loading:false}) Alert.alert('提示',error) // _this.$message.error("登陆失败"); console.log("登陆失败"); }); } onSubmit() { console.log(this.state.times) if(!this.state.qrcode||!this.state.rkNum){ Alert.alert('提交失败', '请输入物料条码和入库数量'); return; } this.addYlJlRk(); } renderParking(){ // 转换为对象数组(符合库要求) // const formattedTableHead = this.state.tableHead.map(title => ({ title })); console.log('tableHead 数据---:', this.state.tableHead); return ( <View> <View style={styles.container}> <Table borderStyle={{borderWidth: 2, borderColor: '#c8e1ff'}}> {/* <Row data={this.state.tableHead} flexArr={this.state.flexArr} style={styles.head} textStyle={StyleSheet.flatten([styles.text])}/> */} <Row data={this.state.tableHead} flexArr={this.state.flexArr} style={styles.head} textStyle={styles.text}/> {/* <Rows data={item.hthList} textStyle={styles.text}/> */} <Rows data={this.state.showCarInfo} flexArr={this.state.flexArr} textStyle={StyleSheet.flatten([styles.text])}/> </Table> </View> </View> ) } render() { let { status, user } = this.props; return ( <Provider> <Header ViewComponent={View } placement="left" leftComponent={{ icon: 'home', color: '#fff', onPress: this.gohome.bind(this) }} centerComponent={{ text: '余料拣货入库扫描', style: { color: '#fff', fontWeight: 'bold' } }} containerStyle={styles.headercontainer} /> <ScrollView> <WingBlank> <View> {/* <Card> <Card.Body> */} <View style={{flex:1,flexDirection: "row"}}> <View style={{flex:9}}> <View> <InputItem clear onBlur={()=>{ }} onChange={value=>{ this.setState({qrcode:value}) }} value={this.state.qrcode} placeholder="请扫描" editable={true}> 物料条码 </InputItem> </View> </View> <View style={{flex:1}}> <Icon name="scan" size="lg" onPress={() => this.scanQrcode()} color="#000000" style={styles.InputIcon}/> </View> </View> <View style={{flex:1,flexDirection: "row"}}> <View style={{flex:10}}> <View> <InputItem clear type="number" onBlur={()=>{ }} onChange={value=>{ console.log('value',value); this.setState({rkNum:value}) }} value={this.state.rkNum} placeholder="单位吨,请输入" editable={true}> 入库数量 </InputItem> </View> </View> {/* <View style={{flex:1}}> <Icon name="scan" size="lg" onPress={() => this.scanRkNum()} color="#000000" style={styles.InputIcon}/> </View> */} </View> {/* <View style={{flex:1,flexDirection: "row"}}> */} {/* <View style={{flex:7}}> </View> <View style={{flex:3}}> */} <Button loading={this.state.loading} onPress={() => this.onSubmit()} type="primary">确认并提交</Button> {/* </View> */} {/* </View> */} <View style={{flex:1,flexDirection: "row"}}> <View style={{flex:3,marginTop:8}}> <Text style={{fontSize:20}}>入库日志</Text> </View> <View style={{flex:7}}> <DatePicker value={this.state.times} mode="date" onChange={this.onChangeDate} format="YYYY-MM-DD" > <List.Item arrow="horizontal"></List.Item> </DatePicker> </View> </View> { this.renderParking() } {/* </Card.Body> </Card> */} </View> <WhiteSpace /> <WhiteSpace /> <WhiteSpace /> <WhiteSpace /> </WingBlank> </ScrollView> </Provider> ); } } export default connect( (state) => ({ status: state.loginIn.status, user: state.loginIn.user, token: state.loginIn.token, }) )(PickingInStorage) const styles = StyleSheet.create({ container: { flex: 1, padding: 2, paddingTop: 10, backgroundColor: '#fff' }, head: { height: 40, backgroundColor: '#f1f8ff' }, text: { margin: 6 }, selectBox: { position: 'relative', }, selectList: { position: 'absolute', top: 50, backgroundColor: '#ccc', height: 150, width: SCREEN_WIDTH, zIndex: 99, }, fontStyle: { fontSize:14 }, selectStyle: { paddingTop:5, paddingBottom:5, height:30, borderTopWidth:1, borderRightWidth:1, borderBottomWidth:1, borderLeftWidth:1, borderLeftColor:'#fff', borderRightColor:'#fff', borderTopColor:'#fff', borderBottomColor:'#fff', }, headercontainer: { marginTop: 0, paddingTop: 0, height: 50, }, beforeInputStyle: { flex: 3 }, afterInputStyle: { flex: 6 //,backgroundColor: "darkorange" }, endInputStyle: { flex: 1.5 //,backgroundColor: "darkorange" ,flexDirection: "row",justifyContent:'flex-end' }, itemStyle: { flex:1,flexDirection: "row" }, getCodeStyle: { flex:1,flexDirection: "row",justifyContent:'flex-end' }, inputStyle: { fontSize: 16,lineHeight:20,height:30, paddingTop:0, paddingBottom:0, // backgroundColor: '#fff', borderTopWidth:1, borderRightWidth:1, borderBottomWidth:1, borderLeftWidth:1, borderLeftColor:'#fff', borderRightColor:'#fff', borderTopColor:'#fff', borderBottomColor:'#fff', }, inputStyle2: { fontSize: 16,lineHeight:20,height:60, paddingTop:0, paddingBottom:0, // backgroundColor: '#fff', borderTopWidth:1, borderRightWidth:1, borderBottomWidth:1, borderLeftWidth:1, borderLeftColor:'#fff', borderRightColor:'#fff', borderTopColor:'#fff', borderBottomColor:'#fff', } }); 这是我整个页面的代码,请看一下我的报错是出在哪里的,怎么解决?
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值