Hello React
react的优点起源简介不再介绍,看文档
react开发依赖
开发react必须依赖三个库
- react --包含react所需核心代码
- react-dom --react渲染在不同平台需要的代码
- babel --将jsx转成react代码的工具 #####如何添加这三个依赖 方式1:直接CDN引入
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
方式2:通过npm管理
###开始hello world
- 先创建一个helloworld.html文件
<div id="app"></div>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
// 通过ReactDom对象来渲染内容
ReactDOM.render(<h2>Hello World</h2>, document.getElementById("app"));
</script>
- 上面的代码解析
- ReactDOM.render函数:
- 这里我们已经提前定义一个id为app的div
- 这里我们传入了一个h2元素,后面我们就会使用React组件
- 参数一:传递要渲染的内容,这个内容可以是HTML元素,也可以是React的组件
- 参数二:将渲染的内容,挂载到哪一个HTML元素上
###类组件
ReactDOM.render第一参数是一个HTML原生或者一个组件。
class App extends React.Component {
render() {
return (<h2>Hello World</h2>)
}
}
ReactDOM.render(<App/>, document.getElementById("app"));
#####数据在哪里定义
-
在组件中的数据,我们可以分成两类:
-
- 参与界面更新的数据:当数据变量时,需要更新组件渲染的内容
- 不参与界面更新的数据:当数据变量时,不需要更新将组建渲染的内容
-
参与界面更新的数据我们也可以称之为是参与数据流,这个数据是定义在当前对象的state中
-
我们可以通过在构造函数中
this.state = {定义的数据} -
当我们的数据发生变化时,我们可以调用
this.setState来更新数据,并且通知React进行update操作 -
在进行update操作时,就会重新调用render函数,并且使用最新的数据,来渲染界面 #####事件绑定中的this
-
在类中直接定义一个函数,并且将这个函数绑定到html原生的onClick事件上,当前这个函数的this指向的是谁呢?
-
默认情况下是undefined
-
很奇怪,居然是undefined;
- 因为在正常的DOM操作中,监听点击,监听函数中的this其实是节点对象(比如说是button对象);
- 这次因为React并不是直接渲染成真实的DOM,我们所编写的button只是一个语法糖,它的本质React的Element对象;
- 那么在这里发生监听的时候,react给我们的函数绑定的this,默认情况下就是一个undefined;
-
我们在绑定的函数中,可能想要使用当前对象,比如执行
this.setState函数,就必须拿到当前对象的this -
我们就需要在传入函数时,给这个函数直接绑定this
- 类似于下面的写法:
<button onClick={this.changeText.bind(this)}>改变文本</button>
class App extends React.Component {
constructor() {
super();
this.state = {
message: "Hello World"
};
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
<button onClick={this.changeText.bind(this)}>改变文本</button>
</div>
)
}
changeText() {
this.setState({
message: "Hello React"
})
}
}
ReactDOM.render(<App/>, document.getElementById("app"));
###JSX语法
jsx表达式
- 书写规则:{表达式}
- 大括号内可以是变量、字符串、数组、函数调用等任意js表达式;
jsx注释
<div>
{/* 我是一段注释 */}
<h2>Hello World</h2>
</div>
jsx嵌入变量
-
情况一:当变量是Number、String、Array类型时,可以直接显示
-
情况二:当变量是null、undefined、Boolean类型时,内容为空;
-
- 如果希望可以显示null、undefined、Boolean,那么需要转成字符串;
- 转换的方式有很多,比如toString方法、和空字符串拼接,String(变量)等方式;
-
情况三:对象类型不能作为子元素(not valid as a React child)
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "why",
age: 18,
hobbies: ["篮球", "唱跳", "rap"],
test1: null,
test2: undefined,
flag: false,
friend: {
name: "kobe",
age: 40
}
}
}
render() {
return (
<div>
{/* 我是一段注释 */}
<h2>Hello World</h2>
</div>
<div>
{/* 1.可以直接显示 */}
<h2>{this.state.name}</h2>
<h2>{this.state.age}</h2>
<h2>{this.state.hobbies}</h2>
{/* 2.不显示 */}
<h2>{this.state.test1}</h2>
<h2>{this.state.test1 + ""}</h2>
<h2>{this.state.test2}</h2>
<h2>{this.state.test2 + ""}</h2>
<h2>{this.state.flag}</h2>
<h2>{this.state.flag + ""}</h2>
{/* 3.不显示 */}
<h2>123{this.state.friend}</h2>
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById("app"));
jsx嵌入表达式
{/* 运算表达式 */}
<h2>{this.state.firstName + " " + this.state.lastName}</h2>
{/* 三元运算符 */}
<h2>{this.state.age >= 18 ? "成年人": "未成年人"}</h2>
{/* 执行一个函数 */}
<h2>{this.sayHello("kobe")}</h2>
jsx属性绑定
<h2 title={this.state.title}>Hello World</h2>
<img src={this.state.imgUrl} alt=""/>
<a href={this.state.link} target="_blank">百度一下</a>
<div className={"message " + (this.state.active ? "active": "")}>你好啊</div>
<div className={["message", (this.state.active ? "active": "")].join(" ")}>你好啊</div>
<div style={{fontSize: "30px", color: "red", backgroundColor: "blue"}}>我是文本</div>
jsx事件监听
class App extends React.Component {
render() {
return (
<div>
<button onClick={this.btnClick}>点我一下(React)</button>
</div>
)
}
btnClick() {
console.log("React按钮点击了一下")
}
}
this绑定问题
-
默认下this是undefined
-
为什么是undefined?
原因是btnClick函数并不是我们主动调用的,而且当button发生改变时,React内部调用了btnClick函数;
而它内部调用时,并不知道要如何绑定正确的this;
如何解决this绑定
-
方案一:bind给btnClick显示绑定this
<button onClick={this.btnClick.bind(this)}>点我一下(React)</button> -
方案二:箭头函数
class App extends React.Component { constructor(props) { super(props); this.state = { message: "你好啊,李银河" } } render() { return ( <div> <button onClick={this.btnClick}>点我一下(React)</button> <button onClick={this.btnClick}>也点我一下(React)</button> </div> ) } btnClick = () => { console.log(this); console.log(this.state.message); } } -
方案三:事件监听时传入箭头函数(推荐)
class App extends React.Component { constructor(props) { super(props); this.state = { message: "你好啊,李银河" } } render() { return ( <div> <button onClick={() => this.btnClick()}>点我一下(React)</button> <button onClick={() => this.btnClick()}>也点我一下(React)</button> </div> ) } btnClick() { console.log(this); console.log(this.state.message); } }
事件参数传递
-
获取event对象
btnClick(e) { e.preventDefault(); console.log(e); }
条件渲染
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLogin: true
}
}
render() {
let titleJsx = null;
if (this.state.isLogin) {
titleJsx = <h2>欢迎回来~</h2>
} else {
titleJsx = <h2>请先登录~</h2>
}
return (
<div>
{titleJsx}
</div>
)
}
}
当然,我们也可以将其封装到一个独立的函数中:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLogin: true
}
}
render() {
return (
<div>
{this.getTitleJsx()}
</div>
)
}
getTitleJsx() {
let titleJsx = null;
if (this.state.isLogin) {
titleJsx = <h2>欢迎回来~</h2>
} else {
titleJsx = <h2>请先登录~</h2>
}
return titleJsx;
}
}
v-show效果
render() {
const { isLogin, username } = this.state;
const nameDisplay = isLogin ? "block": "none";
return (
<div>
<h2 style={{display: nameDisplay}}>{username}</h2>
<button onClick={e => this.loginBtnClick()}>{isLogin ? "退出": "登录"}</button>
</div>
)
}
#####搜索微信公众号《蜗牛和曼巴的前端进程》与你一起交流学习