一、react的引入
需要引入三个文件
1.react.js
https://unpkg.com/react@17/umd/react.development.js
https://unpkg.com/react-dom@17/umd/react-dom.development.js
2.babel.js(因为react是xml编写的,所以需要用babel编译才不会报错)
https://unpkg.com/@babel/standalone/babel.min.js
以上都可以直接引入或者打开连接下载js代码,我是将代码下载本地做演示
<script src="./static/react.development.js"></script>
<script src="./static/react-dom.development.js"></script>
<script src="./static/babel.js"></script>
一定要按照上面的顺序,否则会报错
二、refs标记元素获取DOM实例
1.创建方法getValue:使用箭头函数可以省略bind创建
2.方法中执行获取refs标记元素需要的值
3.ref标记在元素上,等号后面命名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.styleClass {
background-color: red;
color: blue;
}
</style>
<body>
<div id="app"></div>
</body>
<script src="./static/react.development.js"></script>
<script src="./static/react-dom.development.js"></script>
<script src="./static/babel.js"></script>
<script type="text/babel">
// 父组件创建
class Home extends React.Component {
render() {
return (
// 组件嵌套最外层一定要加div
<div>
<Header title={this.props.header} ></Header>
</div>
)
}
}
// 子组件创建
class Header extends React.Component {
constructor(props) {
super(props);
}
//创建方法,点击按钮后执行alert
getValue = () => {
//获取被ref标记的元素,获得输入框中的值
alert(this.refs.msg.value);
}
render() {
// ref命名为msg放置input元素中
return (
<div>
<input ref='msg' />
<h1 className="styleClass">{this.props.title}</h1>
<button onClick={this.getValue}>点击获取内容</button>
</div>
)
}
}
ReactDOM.render(<Home header="头部描述" />, document.getElementById('app'))
</script>
</html>
效果演示,输入框在输入内容后,点击按钮弹出输入内容
三、通过refs子传父
1.首先给父组件创建一个接收子组件数据的方法
2.方法中使用refs来改变父组件元素的内容
3.子组件在方法中,利用this.props来获取方法并调用
<script type="text/babel">
// 父组件创建
class Home extends React.Component {
constructor(props) {
super(props);
}
//父组件创建接收子组件数据的方法
getConentValue = (value) => {
// 方法执行后将值通过refs标记的元素进行内容改变
this.refs.showMsg.innerHTML = value;
}
render() {
return (
// 组件嵌套最外层一定要加div
// 将ref标记在元素上命名showMsg
<div>
<Header title={this.props.header} getConentValue={this.getConentValue} ></Header>
<Content title={this.props.content} isLogin={this.props.isLogin} ></Content>
<Footer title={this.props.footer}></Footer>
<div ref="showMsg">这里等下展示content中文本框的内容</div>
</div>
)
}
}
// 子组件创建
class Header extends React.Component {
constructor(props) {
super(props);
}
//子组件创建方法
getValue = () => {
// 获取子组件标记的input值
var value = this.refs.msg.value
// 调用父组件方法进行子传父,并执行父组件方法使父组件标记的ref元素内容修改
this.props.getConentValue(value);
}
render() {
return (
<div>
<input ref='msg' />
<h1 className="styleClass">{this.props.title}</h1>
<button onClick={this.getValue}>点击获取内容</button>
</div>
)
}
}
class Content extends React.Component {
constructor(props) {
super(props);
}
render() {
// 子组件获取数据做判断
var button = null;
if (this.props.isLogin == 1) {
button = <button>已登录</button>
} else {
button = <button>未登录</button>
}
//将DOM元素存入变量,使用{}可以动态展示
return (
<div>
{button}
<h2>{this.props.title}</h2>
</div>
)
}
}
class Footer extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [1, 2, 3]
}
}
render() {
// 使用map获取list中每个数据进行渲染
// 循环渲染一定要加key,否则或报错
var liList = this.state.list.map(function (item, index) {
return <li key={index}>{item}</li>
})
return (
<div >
<h1 className="styleClass">{this.props.title}</h1>
<ul>{liList}</ul>
</div>
)
}
}
ReactDOM.render(<Home header="头部描述" content='内容描述' footer='底部描述' isLogin='1' />, document.getElementById('app'))
</script>
按钮没点击前
input中输入内容点击按钮文本发生改变
四、子传子
1.子传子需要一个bus来进行数据存储及处理,在react中React.createContext()就是用于存储数据和方法的容器
这里演示使用组件分离式写法,正常框架可以直接用import,我使用的是html写法,所以只能用js文件引入
bus.js代码:主要做储存数据及方法作用
//创建统一储存数据组件
const ThemeContext = React.createContext('100');
home.js代码:父组件,页面最主要页面,映入js,css以及框架文件
在父组件内使用static声明contextType,this.context在组件内才可以被使用,这样可以获取React.createContext('100')后面100的默认值。
然后在父组件render()页面渲染中,添加ThemeContext.Provider,设置数据与运算。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="./static/react.development.js"></script>
<script src="./static/react-dom.development.js"></script>
<script src="./static/babel.js"></script>
<script type="text/babel" src="./bus.js"></script>
<script type="text/babel">
// 父组件创建
class Home extends React.Component {
constructor(props) {
super(props);
}
//使用static声明contextType,this.context在组件内才可以被使用
static contextType = ThemeContext;
render() {
//获取createContext中的默认值100
let num = this.context
return (
// 组件嵌套最外层一定要加div
// 将储存数据标签应用并使用.Provider,在value内可以储存值或方法
<div>
<h1>起始数字{num}</h1>
<ThemeContext.Provider value={{
num,
add: function () {
this.num++
},
reduce: function () {
this.num--
}
}}>
<Child1></Child1>
<Child2></Child2>
</ThemeContext.Provider>
</div>
)
}
}
</script>
<script type="text/babel" src="./child1.js"></script>
<script type="text/babel" src="./child2.js"></script>
<script type="text/babel">
ReactDOM.render(<Home />, document.getElementById('app'))
</script>
</html>
2.子组件注意引入顺序,需要放在父组件之后引入。
子组件中需要使用static声明contextType,this.context在组件内才可以被使用,这样就可以获取bus内的参数与计算方法
child1.js:减法运算并得出结果
class Child1 extends React.Component {
constructor(props) {
super(props);
}
//使用static声明contextType,this.context在组件内才可以被使用
static contextType = ThemeContext;
reduce = () => {
//获取储存器中的减法方法
this.context.reduce();
this.refs.reduceNum.innerHTML = '剪完后得到数字' + this.context.num;
}
render() {
return (
<div>
<button onClick={this.reduce} >减法</button>
<div ref='reduceNum'>剪完后得到数字</div>
</div>
)
}
}
child2.js:加法运算并得出结果
class Child2 extends React.Component {
constructor(props) {
super(props);
}
//使用static声明contextType,this.context在组件内才可以被使用
static contextType = ThemeContext;
add = () => {
//获取储存器中的加法方法
this.context.add();
this.refs.addNum.innerHTML = '加完后得到数字' + this.context.num;
}
render() {
return (
<div>
<button onClick={this.add} >加法</button>
<div ref='addNum'>加完后得到数字</div>
</div>
)
}
}
页面最终结果实现
开始没有数字
点击减法一下显示99
点击加法一下会在得到的99基础上加1等于100