React开发中遇到的问题

一.细节

React的核心思想就是组件化思想,页面会被切分成一些独立的、可复用的组件。

1.React中state和props分别是什么?

 props理解为从外部传入组件内部的数据。由于React是单向数据流,所以props基本上也就是从服父级组件向子组件传递的数据。

一种:跳转页面
父组件addressList:item 是参数对象
	this.props.history.push('/addAddress');
	this.props.routerJump(item,'/addAddress');
	
	
const mapDispatchToProps = (dispatch) => {
	return {
		routerJump: (data,newpathname) => {
		  	dispatch({ 
		    	type: 'globals/pageJump',
		    	payload: {
		    		goodData: data,
	                newpathname:newpathname
	            }
		  	})
		},
	}
}
export default connect(null,mapDispatchToProps)(AddressList);

子组件addAddress:
const mapStateToProps = ({globals}) =>{
	return {
		goodData: globals.goodData
	}
}
export default connect(mapStateToProps,null)(AddAddressWrapper);

const {goodData} = this.props;
console.log(goodData) //就是父组件传下来的参数



二种:直接传值 
父组件addressList:this.state.item 是参数对象
<AddAddress goodData={this.state.item} />

子组件AddAddress:
const {goodData} = this.props;
console.log(goodData) //就是父组件传下来的参数

state的主要作用是用于组件保存、控制以及修改自己的状态,它只能在constructor中初始化,它算是组件的私有属性,不可通过外部访问和修改,只能通过组件内部的this.setState来修改,修改state属性会导致组件的重新渲染。

constructor(props) {
	super(props);
	this.state = {
		Vaddress:'',
		VdoorNum:'',
		Vusername:'',	
		Vdate: now,
	};
}

componentDidMount(){
//1.修改state的值
	this.setState({Vusername:'王晓燕'})  
}
//2.访问state的值
<p>{this.state.Vusername}</p>

区别

 

  1. state是组件自己管理数据,控制自己的状态,可变;
  2. props是外部传入的数据参数,不可变;
  3. 没有state的叫做无状态组件,有state的叫做有状态组件;
  4. 多用props,少用state。也就是多写无状态组件。

2.express开启web服务整体流程

3.React-router4  也就是react-router-dom的一切组件的使用

	/*
		1.withRouter可以包装任何自定义组件,将react-router 的 history,location,match 三个对象传入
		2.Authroute是组件
	*/
	Authroute = withRouter(Authroute);
	export default Authroute

4. react-redux的connect 

/*
		1.Dashboard是组件
		2.mapStateToProps 是state的值
			const mapStateToProps = (state) =>{
				return {users:state.auth}
			}
		3.logout  是redux的action
	*/
	Dashboard = connect(mapStateToProps,{logout})(Dashboard);
	export default Dashboard;

5. 组件属性类型检测  prop-types

static propTypes = {
		name: PropTypes.string.isRequired,//检测字符串
		age:PropTypes.number.isRequired,//检测数字
		user:PropTypes.object.isRequired,//检测对象
		num:PropTypes.array.isRequired,//检测数组类型
		bool:PropTypes.bool.isRequired//检测布尔类型
		fu: PropTypes.func.isRequired,//检测函数(Function类型)
		Symbol: PropTypes.symbol.isRequired//ES6新增的symbol类型
	}

 

二.解决问题

1.react 修改state

一种:简单的修改

constructor(props) {
	super(props);
	this.state = {
		Vaddress:'',
		VdoorNum:'',
	};

}
componentDidMount(){
	this.setState({
		Vaddress:'福建省'
	});
}

 二种:修改state的某个对象所有值

constructor(props) {
	super(props);
	this.state = {
		isbool:false,
		addressDate:{
			Vaddress:'',
			VdoorNum:'',
			Vusername:'',	
			Vdate: now,
			Vsex: 0,
			Vtel:''
		}
	};

}
componentDidMount(){
	const {goodData} = this.props;//这个是父组件穿过 
	if(goodData != ''){
		this.setState({
			addressDate:goodDatas
		});
	}
	console.log(this.state)
}
//输出
{
	addressDate:{
		Vaddress:"福建省福州市闽侯县"
		Vdate:"20018-09-13"
		VdoorNum:" 111号"
		Vsex:0
		Vtel:"18830923940"
		Vusername:"小李子"
		index:11111
	},
	isbool:false,
}

三种:修改state的对象中的某一个属性值

constructor(props) {
		super(props);
		this.state = {
			isbool:false,
			addressDate:{
				Vaddress:'',
				VdoorNum:'',
				Vusername:'',	
				Vdate: now,
				Vsex: 0,
			    Vtel:''
			}
        };
		
	}
	componentDidMount(){
		let goodDatas = Object.assign({},this.state.addressDate,{Vaddress:'福建省福州市闽侯县'})
		this.setState({
			addressDate:goodDatas
		});
		console.log(this.state)
	}
//输出
{
	addressDate:{
		Vaddress:"福建省福州市闽侯县"
		VdoorNum:'',
		Vusername:'',	
		Vdate: now,
		Vsex: 0,
		Vtel:''
	},
	isbool:false,
}

 

2.React的onClick函数如何传参

通过bind(this,参数)的方法就可以在onClick中传参了

<Button onClick={this.showEdit.bind(this, 'add')}>添加用户</Button>


showEdit = (type) => {
	console.log(type)  // 这里面的type就是'add'
	this.setState({ modalType: type, modalVisible: true })
};

3.react动态添加class

1.动态的添加class

	当前元素上没有其他的class
	<div class={'className'}></div>

	当前元素上本身有其他的class,又要动态的添加class时:
	<div class={['className1',index==0?'className2':null].join(' ')}></div>

	或者使用es6中的写法
	<div class={`className1 index==0?'className2':null`}></div>

2.动态的添加style样式
	<div style={{display:(index==0)?"none":"block"}}></div>
	 
	//添加多个样式
	<div style={{display:(index==0)?"none":"block","color":"red"}}></div>
 

dva 中:添加class

1.添加class

this.state={
    isStyle:true
}

<div className={this.state.isStyle?styles.tabsByStyle:null}> 

2.添加style 样式
this.state={
    tabsByStyle:{
                    "position": "fixed",
                    "top": "0px",
                    "zIndex": "9999",
                    "marginBottom": "0.8rem"
    }
}

<div style={this.state.tabsByStyle}> 

还可以引用import classnames from 'classnames'   

import classnames from 'classnames'
const nameI  = "anticon anticon-user";
 <i className={classnames({ [`${nameI}`]: true })}>

4.监听滚动事件

componentDidMount () {
		window.addEventListener( 'scroll', () => {
			let scrollTop = document.documentElement.scrollTop;
			if( scrollTop > 76){
				this.setState({
				    isStyle: true,
				});
			}else{
				this.setState({
				    isStyle: false,
				});
			}
		})
    }

<div className={this.state.isStyle?styles.tabsByStyle:null} />
//上面的意思是  当滚动76的时候 添加tabsByStyle类

5.获取验证码倒计时


class Login extends PureComponent {
	constructor(props) {
		super(props);
		this.state = {
			'count': 60, // 秒数初始化为60秒
			'codeLiked':true // 文案默认为‘获取验证码‘
		};
	}
	    //获取短信验证码
    handleClick = () =>{
    	if(this.state.usertel == ' '){
			Toast.info('请输入手机号码!', 2);
		}else{
			console.log(this.state.codeLiked)
			// codeLiked is false 的时候,不允许再点击
			if (!this.state.codeLiked) {
			 	return
			}
			let count = this.state.count;
			const timer = setInterval(() => {
			    this.setState({count: (count--)},() => {
			        if (count === 0) {
			          	clearInterval(timer);
			          	this.setState({
			            	codeLiked: true,
			            	count: 60
			          	})
			        }else{
			        	this.setState({
			            	codeLiked: false,
			            	count:count
			          	})
			        }
				});
			}, 1000);
		}
    }
	render() {
		return (

				<span onClick={this.handleClick}>
					{ 
						this.state.codeLiked?'获取验证码':(this.state.count + 's')
					}
				</span>
		);
	}
}

6.React直接渲染从后台传过来的标签


<div dangerouslySetInnerHTML={{__html: "<p>明天会更好!</p>"}} />


constructor(props) {
		super(props);
		this.state ={
			html:'<p>明天hi更好</p>'
		}
	}
<div dangerouslySetInnerHTML={{__html:this.state.html}}></div>



// oData.info.info  后端返回的数据
<div className={styles.articlePageInfo} dangerouslySetInnerHTML={{__html: `${oData.info.info}`}}>

 

 

三.错误

(1).setSate的问题

1.Unhandled Rejection (TypeError): Cannot read property 'setState' of undefined

class Login extends React.Component {
	constructor(props){
		super(props);
		//在组件初始化可以直接操作this.state
		this.state={
			Odata:{}
		}
	}
	componentDidMount(){
		console.log('组件加载完毕!')
		axios.get("/data").then(function(res){
            if(res.status === 200 ){
            	console.log(res.data)
            	this.setState({
            		Odata:res.data
            	})
            }
        })
	}
}

上面的代码导致报错,因为this

有2种解决方式:

const that =this;

class Login extends React.Component {
	constructor(props){
		super(props);
		//在组件初始化可以直接操作this.state
		this.state={
			Odata:{}
		}
	}
	componentDidMount(){
		console.log('组件加载完毕!')
		const that = this ;
		axios.get("/data").then(function(res){
            if(res.status === 200 ){
            	that.setState({
            		Odata:res.data
            	})
            }
        })
	}
}

另一种是用箭头函数:

class Login extends React.Component {
	constructor(props){
		super(props);
		//在组件初始化可以直接操作this.state
		this.state={
			Odata:{}
		}
	}
	componentDidMount(){
		console.log('组件加载完毕!')
		axios.get("/data").then((res)=>{
            if(res.status === 200 ){
            	this.setState({
            		Odata:res.data
            	})
            }
        })
	}
}

2.Cannot read property ‘setState’ of null

constructor(props) {
		super(props);
		/*关键就是这里,把要使用this的函数  在构造函数中用bind方法传入this*/
		this.startFu = this.startFu.bind(this);
		this.state = {
			data:{}
		};
	}
	startFu(){
		this.setState({data:res.data})
	}

绑定this就可以

3.Cannot read property 'push' of undefined  react

问题:在子组件使用history跳转时失败
this.props.history.push('/detailInfo'); 就报报错

原因:
Router 组件的后代里头才没有 this.props.history ,所以子组件没有push这个函数。

解决方法:

在父组件传递:history={this.props.history}/

 <ListInfo  ListData={this.state.ListData} history={this.props.history}/>

4.this.setState is not a function

问题:在函数里面执行this,setState

	setTimeout(function(){
      		this.setState({
	      		[key]: false
	    	});
      	},100);

解决方式是改成箭头函数

setTimeout(() => {
      		this.setState({
	      		[key]: false
	    	});
      	},100);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值