1.jsx基础语法,但是是在单个html文件中使用
一、先引入
1. react react核心脚本
2. react_dom react处理dom渲染的核心脚本
3. babel 转换文件,把jsx语法转成这个正常浏览器能够识别的语法
二、然后给script标签对添加 type = "text/babel"
三、写代码
<div id='app'></div>
<script type="text/babel">
var hello = <h1>Hello World</h1>
// 通过calssName添加类名
var computer = <div className="num computer">{3 * 5}</div>
// 条件渲染的方式 vue使用v-if,react是使用if和else判断
var content = Math.random() > 0.5 ? <i>大于0.5</i> : <b>小于0.5</b>
var content2 = Math.random() > 0.5 && <h2>大于0.5</h2>
// 循环渲染 vue通过v-for react通过
var arr = ["国际", "银行", "富士康"];
var content3 = <ul>
{
arr.map(item => {
return <li key={item}>{item}</li>
})
}
</ul>
// 可以在js中写上style对象的css样式绑定到标签的style属性上,形成标签的行内样式
// 不能循环渲染对象的每一个属性,但是可以打点渲染对象的某个属性对应的属性值
var student = {
name:"张三",
age:12
}
var obj = {
fontSize:'20px',
color:"#f0f000"
}
var test= <div style={obj}>{student.name}</div>
var root = ReactDom.createRoot(document.getElementById('app'))
// 在jsx中注释通过{/**/}
root.render(<div>
{hello}
{computer}
{content}
{content2}
{content3}
{test}
</div>)
</script>
2.组件
无状态组件(函数式组件)和有状态组件(类组件);状态指的是响应式数据
// 无状态组件(函数式组件):通过es5的构造函数创建的组件。不能声明状态(响应式数据),主要是用实现一些简单的功能的组件,主要是用进行展示的。
// 有状态组件(类组件) 通过类进行创建的,可以定义状态,可以实现一些比较复杂的业务逻辑。
//函数式组件
function MyCom() {
// return 返回的组件的模板 模板结构比较复杂的时候,可以整体用一个()包裹起来,当成一个整体
return(
<div>
<h1>我是一个函数式组件</h1>
</div>
)
}
// 定义类组件继承于React.Component
class MyCom2 extends React.Component{
// 会在此处定义响应式数据(状态)
constructor(){
// 调用父类的构造函数,继承过来父类初始化的数据
super()
this.state = {
age:10101010
}
}
// 渲染函数 里面返回页面的模板结构
render(){
return(
<div>我是类组件{this.state.age}</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("app"))
root.render(
<div>
<MyCom></MyCom>
<MyCom2></MyCom2>
</div>
)
3.类组件中使用事件绑定与事件传参
// (改变this指向):在类组件中定义方法,然后再调用或者定义使用更改this指向,使this指向组件对象;
// (修改状态值):然后修改使用状态数据是通过this.setState()进行修改
// (向函数中传递参数):通过bind的第二个参数传递参数,对应函数函数中的形参.或者在绑定函数的标签上设置data-age的属性。函数通过e.currentTarget.dataset.age来收到参数;
class MyCom extends React.Component{
constructor(){
super()
this.state = {
count:1
}
this.add = this.add.bind(this);
}
// 如果事件函数式普通函数,里面的this是undefine的,不能在普通函数里面通过this访问其他数据
// 1.通过在构造函数constructor可以对普通函数进行修改this绑定
add(){
console.log(this,"1111111111");
// react修改state数据通过setState方法进行修改
this.setState({
count:this.state.count+1
})
}
// 1.2 在调用的时候更改this绑定
sub(){
this.setState({
count:this.state.count-1
})
}
// 1.3 设置一个箭头函数,这个时候不用再更改this的指向
add2 = ()=> {
console.log(this);
this.setState({
count:this.state.count*2
})
};
// 事件传参的函数 通过调用时候bind绑定传参
add3 = (data)=> {
console.log(this);
this.setState({
count:data
})
};
// 事件传参的里函数 通过data-age属性传参
add4 = (e)=> {
console.log(e,e.currentTarget.dataset.age);
this.setState({
count:e.currentTarget.dataset.age*1
})
};
render(){
return(
<div>
{/*1.绑定一个普通函数,通过onClick进行绑定函数,函数定义的时候在类结构里面进行定义*/}
<button onClick={this.add}>绑定一个普通的函数,在constructor中更改this指向---{this.state.count}</button>
{/*2.绑定一个普通函数,在调用方法的时候更改this绑定*/}
<button onClick={this.sub.bind(this)}>绑定一个普通的函数,调用的时候修改this的指向---{this.state.count}</button>
{/*3.绑定一个箭头函数,这个时候的this指向组件对象*/}
<button onClick={this.add2}>绑定一个箭头函数,直接调用函数---{this.state.count}</button>
{/*4.绑定一个箭头函数,直接在标签中写函数*/}
<button onClick={()=>{
this.setState({
count:this.state.count/2
})
}}>绑定一个箭头函数,函数体直接写在onClick的jsx中---{this.state.count}</button>
{/*5 事件函数传参数,bind传参*/}
<button onClick={this.add3.bind(this,"30")}>通过bind传参</button>
{/*6 事件函数参数*/}
<button onClick={this.add4} data-age="50">通过data-属性和e传参</button>
</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("app"))
root.render(
<div>
<MyCom></MyCom>
</div>
)
4.组件通信
4.1 父组件向子组件传值 (属性传值与插槽传值)
/*
自定义属性传值:
函数式子组件接受类父组件传递的数据: 调用子组件的标签上加上自定义属性,函数子组件通过形参.自定义属性名来接受传递来的值
类子组件接受类父组件传递的数据: 调用子组件的标签上加上自定义属性,类子组件通过(this.(在render中使用需要加上this))constructor的形参来.自定义属性名来接受传递来的值
插槽传值:
函数式子组件接受类父组件传递的数据: 调用子组件的标签对中加上内容,函数子组件通过形参.children来接受传递来的值
类子组件接受类父组件传递的数据: 调用子组件的标签上加上自定义属性,函数子组件通过(this.(在render中使用需要加上this))constructor的形参来.自定义属性名来接受传递来的值
插槽内容:
换行不会被写入children中;
插槽内容中存在多个标签的时候,会以数组的元素形式存在;
标签与标签在一行,中间有空格,空格也会占据一个元素;
*/
//函数式组件父传子
function Child(prop) {
// prop.children 是插槽传递的值 prop.msg 是自定义属性传递的值
console.log(prop);
return(
<div>
函数子组件--{prop.msg}--{prop.children}
</div>
)
}
// 类组件 子组件
class Son extends React.Component{
constructor(props){
super();
console.log(props,222);
this.state={
age:20
}
}
render(){
return(
<div>
类子组件--{this.props.msg}--{this.props.children}
</div>
)
}
}
// 父组件
class Father extends React.Component{
constructor(props){
super()
// 状态
this.state={
mes:'郑州'
}
}
// 不要在render函数中调用setState()函数
// 如果在render函数中设置setState之后,那么在界面需要更新时候,需要调用render函数;render中再调用setState函数,就等同于在render调用自己,造成死循环
render(h){
return (
<div>
<Child msg="hello">{this.state.mes}</Child>
<Son msg="hello">{this.state.mes}</Son>
</div>
)
}
}
ReactDOM.createRoot(document.getElementById("app")).render(<div><Father></Father></div>)
4.2 子组件向父组件传递数据
// 修改父组件的name字段,修改函数压定义在父组件里面,目的是为了数据能够更好追踪字段的变化;
/* 子传父,react中把父组件的函数传递给子组件,在子组件进行调用并且传参
函数子组件
1.在父组件中定义修改state中数据的方法,用形参来接收参数;
2.在使用子组件标签上使用自定义属性将方法传递给子组件;
3.子组件模板中设置触发子组件传值给父组件的方式(onClick...),并设置对应的触发函数;
4.在子组件中被触发的函数中接收父组件传递的函数,并进行调用自定义的属性,然后传递给自定义属性的函数的值;
类子组件与上面函数子组件不同的是在第四步;函数式子组件没有自身的状态值,会传递一个input框的值;
类子组件会将自身的状态值作为传递的实参
*/
// 父组件有一个数据a,需要把子组件的数据传递给父组件的a状态
function Com(props) {
// input输入的时候触发子组件的自定义函数
// 取出父组件传递的函数并且在组件里面进行调用并且传参
function send(e) {
// 调用在组件标签上的自定义事件,并传递参数
// 取出父组件传递的函数并且在子组件及您修改调用并且传参
props.myChange(e.target.value)
console.log(props.children);
}
return (
<div>
函数子组件:<input type="text" onChange={send} placeholder={props.children} />
</div>
)
}
class Son extends React.Component {
constructor(props) {
super()
this.state = {
name: 'aaa'
}
}
send = () => {
this.props.myChange(this.state.name)
}
render() {
return (
<div>
<button onClick={this.send} >
点击传递类组件中的数据</button>
</div>
)
}
}
// 父组件
class Father extends React.Component {
constructor(props) {
super()
this.state = {
name: 'zs'
}
}
// 定义一个修改的方法
changeName = data => {
console.log(data);
this.setState({
name: data
})
}
render() {
return (
<div>
父组件name:{this.state.name}
{/* 通过自定义属性把函数传递过去 */}
<Com myChange={this.changeName} name={this.state.name}>{this.state.name}</Com>
<hr></hr>
父组件age:{this.state.name}
{/* 通过自定义属性吧函数传递过去 */}
<Son myChange={this.changeName} name={this.state.name}>{this.state.name}</Son>
</div>
)
}
}
ReactDOM.createRoot(document.getElementById("app")).render(<div><Father></Father></div>)