react04---

1、refs 参照
this.refs —> 对象,存放的是组建中使用ref属性,并且属性值为字符串的,将node节点保存到refs中。
DOM对象
event.target 可以获取

挂载在组件上

//子组件
import React from 'react;
class MyRefs extends React.Component{
	constructor(props){
		super(props);
		this.state = {};
	}
	//willMount willUpdate将被废弃
	componentDidMount(){
		//保存该组件内有ref属性,并且属性值为字符串的元素
		console.log(this.refs);//
	}
	render(){
		return (
			<div>
				<h3 ref="hello">hello</h3>
				<h3 ref="world">world</h3>
			</div>
		);
	}
}
export default MyRefs;
//父组件
import React from 'react';
import './App.css';
import MyRefs from './components/1-MyRefs';
// console.log(MyRefs);  //只是一个导入的东西不完整
// console.log(MyRefs.state);  //undefined 拿不到导入的子组件的state,子组件的state只允许在子组件内部访问
class App extends React.Component {
  componentDidMount() {
    console.log(this.refs);
    console.log(this.refs.myrefs); //组件实例
    console.log(this.refs.myrefs === MyRefs); //false
    console.log(this.refs.myrefs.state); //msg
	
	//父组件通过refs来修改子组件的state中的值的方法
    //this.setState({},()=>{}); 第一个参数要修改的内容,第二个参数是一个回调函数,当页面渲染结束触发的函数
    this.refs.myrefs.setState({ msg: 'hello1111' }, () => {
      console.log(this.refs.myrefs.state.msg);
    });
  }
  render() {
    return (
      <div>
        <MyRefs ref="myrefs"></MyRefs>
      </div>
    );
  }
}
export default App;

2、父组件修改子组件中的state中的数据的方法
思路:如果父组件中拿到子组件的实例,就可以通过子组件的实例调用setState去更改子组件state的数据。

子组件改父组件state数据:需要父组件传递修改自己state的函数给子组件调用;

父组件:

import React,{Component} from 'react';
calss Pc extends Component{
	constructor(props){
		super(props);
		this.state = {
			parentMsg:'parentMsg'
		};
	}
	handle = ()=>{
		//获取子组件的实例对象
		const myc = this.refs.myc;
		console.log(myc.state.msg);
		myc.setState({
			msg:'hello'
		})
	}
	//更改父组件的state数据
	changeParentState = () =>{
		this.setState({
			parentMsg:'parentHello'
		})
	}
	render(){
		return (
			<div>
				<button onclick={this.handle}>点击更改子组件中的state中的msg</button>
				<MyC ref="myc" parentMsg={this.state.parentMsg} changeParentState={this.changeParentState}></MyC>
			</div>
		)
	}
}
export default Pc;

子组件:

import React,{Component} from 'react';
class MyC extends Component{
	constructor(props){
		super(props);
		this.state = {
			msg:'msg';
		};
	}
	render(){
		return (
			<div>
				<h3>{this.state.msg}</h3>
				<h2>接收父组件中的数据:{this.props.parentMsg}</h2>
				<button onClick={this.props.changeParengtState}>更改父组件中的数据</button>
			</div>
		);
	}
}
export default MyC;

3、ref值为回调函数:在组件被加载或卸载的时候会调用回调函数

<div ref={(node)=>{console.log(node,'-----')}}>ref值为回调函数</div>

4、JSX中写style

import React,{Component} from 'react';
//引入外部样式,这里可以写sass样式
import './Style.css';
class Style extends Component{
	//
	let btnStyle = {
		backgeroundColor:'teal',
		width:100,
		border:'none',
		fontSize:30
	};
	render(){
		return (
			<div className="Style">
				<span style={{color:'red',fontSize:12,}}>
					hello
				</span>
				<button style={btnStyle}></button>
				<h3></h3>
			</div>
		)
	}
}

5、双向数据绑定
input text
输入框中的内容发生改变的视乎,数据模型中预支对应的数据发生更改。
数据模型中的数据发生更改的时候,输入框中的内容发生改变。

import React,{Component} from 'react';
class MyFrom extends Component{
	constructor(props){
		super(props);
		this.state = {
			inputValue :'inputValue'
		};
	}
	render(){
		retun (
			<div>
				<form>
					用户名:
					<input value={this.state.inputValue} onChange={this.changeHandle} type="text" />
				</form>
			</div>
		)
	}
}
export default MyForm;
//多种表单控件的双向数据绑定,state
//在当前组件中有很多数据,其中有一个数据存放的是模态框表单的数据
import React,{Component} from 'react';
class MyForm extends Component{
	constructor(props){
		super(props);
		this.state = {
			//页面显示男,女,传递后台male,female
			genders:[{
				name:'男',
				value:'male'
			},{
				name:'女',
				value:'female'
			}],
			//地址
			address:[{
				name:'江苏',
				value:'jiangsu'
			},{
				name:'江西',
				value:'jiangxi'
			},{
				name:'山西',
				value:'shanxi'
			}],
			hobby:[{
				name:'游泳',
				value:'swimming'
			},{
				name:'跳舞',
				value:'dancing'
			},{
				name:'阅读',
				value:'readding'
			}],
			msg:'注册页面',
			form:{
				username:'',
				age:'',
				gender:'',
				address:'',
				desc:'',
				//用户选中的复选框的数据
				hibbies:[]
			}
		};
	}
	//change事件处理程序
	inputChange = (attr,e)=>{
		//先获取到副本form,修改副本中的username,再设置到state的form上
		//方法一
		//let form = Object.assign({},this.state.form);
		//form[attr] = e.target.value;
		//this.setState({
			//form
		//})
		
		//方法二
		this.setState({
			form:{
				...this.state.form,
				[arrr]:e.target.value
			}
		});
	}
	toSubmit = (e)=>{
		console.log(this.state.form);
	}
	radioChange = (e)=>{
		let form = Object.assign({},this.state.form);
		form.gender = 
	}
	checkboxChange = (e)=>{
		//如果数组中没有它的值,添加,否则,删除
		let value = e.target.value;
		let hobbies = [...this.state.form.hobbies];
		if(hobbies.includes(value)){
			//执行移除
			//找到当前元素的索引,然后通过索引删除
			let index = hobbies.indexOf(value);
			hobbies.splice(index,1);
		}else{
			//执行添加
			hobbies.push(value);
		}
		this.setState({
			form:{
				...this.state.form,
				hobbies
			}
		},()=>{
			console.log(this.state.form.hobbies);
		})
	}
	render(){
		//const form = this.state.form;将form解构出来,方便书写
		const {form} = this.state;
		return (
			<div className="MyForm" style={{padding:20}}>
				<h3>{this.statemsg}</h3>
				<form action="">
					用户名:<input type="text" value={form.username} onChange={this.inputChange.bind(this,'username')} /><br/>
					年龄:<input type="number" value={form.age} onChange={this.inputChange.bind(this,'age')} /><br />
					性别:{
						this.state.genders.map((item,index)=>{
							return (
								<lable htmlFor="" key={index}>
									<input type="radio" onChange={this.state.inputChange.bind(this,'gender')} value={item.value} checked={form.gender == item.value? true: flase} />{item.name}
								</lable>
							)
						})
					}
					地址:<select value={form.address} onChange={this.inputChange.bind(this,'address')} name="" id="">
							<option value="">请选择</option>
							{
								this.state.address.map((item,index)=>{
									<option value={item.value} key={index}>{item.name}</option>
								});
							}
						</select><br/>
					描述:<textarea onChange={this.state.inputChange.bind(this,'desc')} value={form.desc} name="" id="" cols="30" rows="10"></textarea>
					爱好:{
						this.state.hobby.map((item,index)=>{
							return(
								<label htmlFor={item.value} key={index}>
									<input id={item.value} type="checkbox" value={item.value} checked={form.hobbies.includes(item.value)} onChange={this.checkboxChange}/>{item.name}
								</label>
							)
						});
					}
				</form>
				<button onClick={this.toSubmit}>提交</button>
			</div>
		);
	}
}

5、css模块化导入与使用

方法一、配置WbePack模块化导入css
1、执行	yarn eject 或 cnpm run eject	命令,在新项目创建好之后,将webPack配置文件暴露出来;遇到问题输入y即可;
2、找到 config-> webpack.config.js 文件,将438,439行的
modules:true,//开启css模块化
getLocalIdent:getCSSModuleLocalIdent,
这两行复制到上一个use的最后一行(即,在检测css的地方),此时在导入css时就是以模块的形式导入
3、运行项目
4、src目录下新建文件夹components,之下新建TestCss.js和TestCss.css(注意:css文件不能以数字开头,会导致样式文件无效)
5、在js文件下
import React,{Component} from 'react';
//注意这个地方引入css文件跟以往有所区别,css模块化处理之后,将不再直接导入运行,而是直接导入一个对象;
import style form './TestCss.css'
class TestCss extends Component{
	render(){
		return (
			<div>
				{/*注意,这里在使用的时候也有变化,要从对象.属性名的形式调用*/}
				<span className={style.one}>hello</span>
				<span id={style.two}>world</span>
			</div>
		)
	}
}
export default TestCss;

在css文件下

.one{
	color:red;
}
#two{
	color:green;
}
方法二:在react项目中使用Sass(推荐)
以.sass和.scss结尾的文件都是Sass文件,.scss结尾的文件可以用css嵌套写
1、安装sass环境,执行命令
yarn add node-sass
2、运行项目
3、src目录下新建文件夹components,之下新建TestSass.js和TestSass.scss
4、在js文件下
import React,{Component} from 'react';
import './TestSass.scss';
class TestSass extends Component{
	render(){
		return (
			<div className="TestSass">
				<span className={style.one}>hello</span>
				<span>world</span>
			</div>
		)
	}
}
export default TestSass;

在scss文件中

.TestSass{
	span{
		color:red;
	}
	span:last-child{
		color:blue;
	}
	.one{
		font-size:20px;
	}
}

5、路由
hash路由
localhost:3000/#/student

浏览器路由
localhost:3000/student

实现选项卡、导航的切换

import React,{Component} form 'react';
//导入组件
import Student form './Student';
import Child form './Index';
import Teacher form './Teacher';
import Course form './Course';

class MyTab extends Component{
	constructor(props){
		super(props);
		this.state = {
			CurrentCom:Index
		}
	}
	//点击切换
	changeTab = (component)=>{
		this.setState({
			CurrentCom : component
		})
	}
	render(){
		//CurrentCom 就是某个组件,解构之后可以用标签展示在页面上
		let {CurrentCom} = this.state;
		return (
			<div>
				<nav>
					<button onClick={this.changeTab.bind(this,Index)}>首页</button>
					<button onClick={this.changeTab.bind(this,Student)}>学生管理</button>
					<button onClick={this.changeTab.bind(this,Teacher)}>教师管理</button>
					<button onClick={this.changeTab.bind(this,Course)}>课程管理</button>
				</nav>
				<div>
					<CurrentCom></CurrentCom>
				</div>
			</div>
		)
	}
}

准备好 首页,学生管理,教师管理,课程管理 四个组件,分别导出。

在项目中引入路由

1、在项目中安装react-rout-dom插件。执行命令  yarn add react-router-dom
2、启动项目
3、src目录下新建文件夹components,之下新建MyRoute.js
//yarn add react-router-dom
import React,{Component} from 'react';
import {BrowserRouter,HashRouter,Switch,Link,Route,navLink,Redirect} from 'react-route-dom';
//引入组件
import Student form './Student';
import Child form './Index';
import Teacher form './Teacher';
import Course form './Course';
import './MyRoute.scss'
class MyRoute extends Component{
	render(){
		return (
			//推荐使用<HashRouter></HashRouter>写路由
			<BrowserRouter>
				<nav>
					//可以用 <navLink> 设置选中的样式,cativeClassName处于活动状态时的样式,exact完全匹配
					<navLink exact  cativeClassName="navActive" to="/">首页</navLink>
					<Link exact to="/student">学生管理</Link>
					<Link exact to="/course">课程管理</Link>
					<Link exact to="/room">教室管理</Link>
					<Link exact to="/teacher">教师管理</Link>
				</nav>
				<div>
					{/*展示的组件*/}
					<Switch>
						<!--重定向 -->
						<Redirect from="/" to="/student"></Redirect>
						<!--exact 完全匹配路由-->
						<Route exact path="/" component={Index}></Route>
						<Route path="/student" component={student}></Route>
						<Route path="/course" component={course}></Route>
						<Route path="/room" component={room}></Route>
						{/*使用render可以方便的进行内联渲染和包装,而无需进行上下文解释的不必要的组件重装*/}
						<Route path="/teacher" render={()=>{return <div>hello</div>;}}></Route>
					</Switch>
				</div>
			</BrowsRouter>
		)
	}
}
export default MyRoute;

MyRoute.scss

.navActive{
	color:teal;
}

7、API跳转
this.props.history.push(’/content’)
//跳转传递参数
this.props.history.push({
pathname:’/content’,
state:{
name:‘zhangsan’,
age:12
}
})
//接收传递的参数
componentDidMount(){
//api传参,参数存放的位置
console.log(this.props.location);
//查询字符串参数的获取
console.log(this.props.location.search);
//获取动态路由的参数
console.log(this.props.match);
}

8、url传参

//使用动态路由
<Route path='/course/:id' component={Course}></Route>
<NavLink activeClassName='navActive' to='/course/4'>课程管理</NavLink>
//参数获取
this.props.match.params.id

9、查询字符串传参
/studentDetails?name=zhangsan
参数获取:通过 this.props.location.search来获取参数

10、其他跳转

<Link to={{
	pathname:'/courses',//传递的pathname
	serach:'?sort=name',//传递的URL参数
}} />

//在courese获取参数
componentDidMount(){
	//接收其他组件传递的数据
	console.log(this.props.location);
	
}
<a href="#/student">a标签跳转</a>

总结:

路由跳转
1. API跳转
this.props.history.push(’/course’)
2.NavLink
</>
3.Link

4.a

路由传参
API路由传参
this.props.history.push({
pathname:’’,
state:{
test:‘test’,
obj:{}
},
test:’’
})
获取
this.props.location.test
this.props.location.state
查询字符串传参
/course?name=zhangsan
获取
this.props.location.search
动态路由传参
先配置
<Route path="/course/:test component={Course}>
跳转四种方法都可以,/后面带任何东西
/course/hello
获取
this.props.match.params.test

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值