基础与组件
1.安装脚手架 【CRA】
cnpm install -g create-react-app
2.创建项目
create-react-app projectname
3.启动项目
cnpm start //启动
cnpm run build //打包
4.项目目录结构
└── node_modules 项目依赖目录
├── public 静态公共目录【不会被编译压缩打包,原样输出】
├── src 开发用的源代码目录
- index.js 项目入口文件
- index.css 项目全局样式
- App.js 项目最大的组件【类似根组件】
- App.css App组件的样式文件
- App.test.js App组件测试文件
- logo.svg 初始项目的界面logo
- serverWorker 内部文件,我们不操作
├──.gitgnore 项目git上传忽略文件
├── package.json 项目依赖配置记录文件,记录项目脚本命令
├── README.md 使用方法的文档
|-- config 项目webpack配置文件
|-- scripts 项目wepback脚本命令执行文件
└── yarn-lock.json 锁定安装时的包的版本号,保证团队依赖能一致
5. 入口文件【index.js】
import React from 'react' //JSX语法依赖
import ReactDOM from 'react-dom' //React组件渲染到页面上,是从react-dom中引入的
import App from './App'; //引入根组件
ReactDOM.render( //ReactDOM里render方法,把组件渲染成DOM树,插入页面元素中
<App/>, //组件名必须大写
document.getElementById('root') //必须是DOM元素
);
6.函数式组件【app.js根组件】
import React from 'react' //JSX语法依赖
import ReactDOM from 'react-dom' //React组件渲染到页面上,是从react-dom中引入的
const App = (props) => <h1>我的名字是{props.name}</h1>
ReactDOM.render(
<App name="react" />
document.getElementById('root')
)
export default App; //导出组件
这样一个完整的函数式组件就定义好了。但要注意!注意!注意!组件名必须大写*,否则报错。
7.类组件【page/Home.js】
import React from 'react' //JSX语法依赖
import ReactDOM from 'react-dom' //React组件渲染到页面上,是从react-dom中引入的
class Home extends React.Component {
render () {
return (
// 注意这里得用this.props.name, 必须用this.props
<h1>欢迎进入{this.props.name}的世界</h1>
)
}
}
ReactDOM.render(
<Home name="react" />,
document.getElementById('root')
)
export default Home; //导出组件
功能复杂用类组件,功能单一用函数式组件
8.组件俩种样式
1.行内样式
// 注意这里的两个括号,第一个表示我们在要JSX里插入JS了,第二个是对象的括号
<p style={{color:'red', fontSize:'14px'}}>Hello world</p>
2.安装第三方插件
cnpm i styled-components -D
import style from 'styled-components'
const container = styled.div`
background:red;
`
<container>
内容
</container>
9.组件组合和嵌套【建议用嵌套】
- 组件的嵌套式指: 将子组件在父组件的jsx中以标签的形式使用
- 组件的组合是指:将一个组件写在另一个组件的内容中,然后在外层组件中通过 this.props.children来接收内容中的组件
- 但是我们推荐大家后面写的话可以使用嵌套
10.组件的数据
【属性props】
属性props不会轻易改变
1.外部属性
在根组件的标签中添加属性,在组件自身就能接收到,在自身中使用{this.props.xxx}就能输出,如果有多个属性,这可以在开头先解构this.props
const props=this.props
2.内部属性
在自身组件内部添加以下代码
static defaultProps = {
name: 'React' //属性名:‘属性值’
}
有多个属性,也需要解构this.props
属性验证
$ cnpm i prop-types -S
//需安装第三方插件
1.引入 import propTypes from 'prop-types'
组件名.propTypes={
属性名:PropTypes.验证类型【sting...】
}
【状态state】
跟组件一样,写在类class函数中,区别于属性是可以变动,自己的状态自己修改
state = {
name: 'React',
}
<h1>欢迎来到{this.state.name}的世界</h1> 使用方法也是先解构在使用
方式二【官方推荐】
constructor() {
super()
this.state = {
name: 'React',
}
}
更改状态
changeMsg=()=>{
this.setState({
msg:'新内容'
})
}
//setState可以有两个参数,参1是数据修改的参数,可是对象,也可以是回调函数,参2是异步回调函数
<button onclick={this.changeMsg}>更改状态<button
11.状态提升
果有多个组件共享一个数据,把这个数据放到共同的父级组件中来管理
12.受控组件与非受控组件
受控组件:父组件获取数据传参到子组件,子组件的数据都由父组件操控.
13.两种事件的写法
1.在组件内使用箭头函数定义一个方法(推荐)
2.直接在组件内定义一个非箭头函数的方法,然后在constructor里bind(this)(推荐)
14.事件传参
在`render`里调用方法的地方外面包一层箭头函数
15.表单用户输入
constructor(props){
super(props)
this.state={
val:''
}
}
changeVal=(e){
const newval=e.taget.value
this.setState({
val:newval
})
}
<input type="text" onkeyUp={this.changeVal}/>
16.表单属性问题
Value->defaultValue checked->defaultChecked
17.组件通信
1.父子组件通信
在父组件状态state中定义数据,子组件通过{...this.state}解构接收
2.子父通信
父组件定义一个方法,子组件通过{this.方法}接收
子组件定义数据,在自身中添加事件,将父组件方法外层包箭头函数,并解构后传入子组件自身的参数
3.非子父通信
先子父,再父子,以父为中间站传递数据
4.跨组件通信【爷传孙通信】
首先在public中创建上下文
import {createContext} from 'react'
const MoneyContext = createContext(100) //100是默认值
exprot default MoneyContext
在爷组件中引入创建的上下文组件
用
const money=this.state
<MoneyContext.provider value={money}>
<Father></Father>
</MoneyContext.provider>
在孙组件中进入上下文
static contextType = MoneyContext
<p>爷爷给了我{this.context}