React 面向组件化编程javascript
面向对象 ----> 面向模块 ----> 面向组件css
套路:html
注意: java
组件名必须大写开头;node
只能有一个根标签;react
<input />虚拟DOM 元素必须有结束标签面试
方式1. 工厂函数组件 (简单组件) ----> 只能定义无状态的组件npm
function MyComponent(){ // 只能 大写开头,区别于普通函数 return <h2>工厂函数组件(简单组件)</h2> }
// 渲染函数组件标签
// 内部直接调用 工厂组件函数 获得虚拟组件函数 ReactDOM.render(<MyComponent/>, document.getElementById("outer"))
方式2: ES6 类组件 (复杂组件)编程
class MyComponent2 extends React.Component { // 1. 必须继承 // 2. 必须大写开头 // 3. 必须重写 render 方法, 指定 return 返回值 render (){ return <h2>ES6类组件(复杂组件)</h2> } }
// 渲染类组件标签
// 内部会自动建立类的实例,并调用其 render() 方法获得须要渲染的虚拟 DOM ReactDOM.render(<MyComponent/>, document.getElementById("outer"));
// 获取到虚拟 DOM 对象 页面上的 原生 DOM
组件的三大属性:数组
面试题: 区别一下组件的 props 和 state 属性
相同点: 都是组件实例的对象,用于保存数据
不一样点:
state 保存组件自身内部可变化的数据
props 保存从外部传入组件内部的数据,组件内部只读而不修改
是组件对象最终要的 属性,属性值是一个对象 (能够包含多个)
组件被称为 "状态机"
更新状态 从而 更新界面 ----> this.setState({stateName1 : newValue})
this.state 是组件私有的,经过调用 this.setState() 来改变它
this.setState() 每次修改之后,自动调用 this.render 方法,再次渲染组件
能够经过 getInitialState() 方法初始化,在组件的生命周期中仅执行一次
var FavoriteButton=React.createClass({ getInitialState:function(){ return {favorite:false}; }, handleClick:function(event){ this.setState({favorite:!this.state.favorite}); }, render:function(){ var text=this.state.favorite? 'favorite':'un favorite'; return ( <div type='button' onClick={this.handleClick}> You {text} this. Click to toggle. </div> ); } }); --------------------- 做者:CrazyCodeBoy 来源:CSDN 原文:https://blog.csdn.net/fengyuzhengfan/article/details/52185921 版权声明:本文为博主原创文章,转载请附上博文连接!
当 state 更新以后,组件就会从新渲染本身。
render() 方法依赖于 this.props 和 this.state ,
框架会确保渲染出来的 UI 界面老是与输入( this.props 和 this.state )保持一致
实例: iLikeQuQ
class Like extends React.Component { // 组件类 constructor(props){ super(props) this.state = {isLikeMe: false} }
// 组件中自定义的方法的 this 默认指向 undefined
// 利用 箭头函数 没有本身的 this 来 在函数内使用 this
// 若要 更新组件的显示,必须使用 组件的 setState() chgText = ()=>{ // this.state.isLikeMe = !this.state.isLikeMe 无效操做 this.setState({ isLikeMe: !this.state.isLikeMe }) } render(){ const isLikeMe = this.state.isLikeMe const text = isLikeMe?"I Like U.":"U Like Me." return <h2 onClick={this.chgText}>{text}</h2> } }
ReactDOM.render(<Like/>, document.getElementById("outer"));
每次点击,改变了 状态,那么就会自动从新调用 render() 方法
props 对象
每一个组件只会根据 props 渲染了本身一次,props 是不可变的
<script src="https://cdn.bootcss.com/prop-types/15.6.2/prop-types.js"></script>
class Person extends React.Component { /**** 默认会执行 constructor (props){ super(props); // props 包含了组件标签的全部属性数据 } ****/ render(){ const {name, age, sex} = this.props; return ({ <ul> <li>姓名: {name}</li> <li>年龄: {age}</li> <li>性别: {sex}</li> </ul> }) } } // this.props.xxx // 1. 读取属性名 xxx 对应的 属性值 Person.propTypes = { // 2. 设置 props 中属性的约束条件 name: PropTypes.string.isRequired // 必须传参,且 string } Person.defaultProps = { // 3. 设置 props 中属性的默认值 age: 18, sex: "未知" } /**************************************/ const sun = { name: "孙悟空", age: 550, sex: "男" } // name 被 isRequired 修饰,必须传,且类型必须为 string ReactDOM.render(<Person name={sun.name} age={sun.age} sex={sun.sex}/>, document.getElementById("outer")); // ReactDOM.render(<Person {...sun}/>, document.getElementById("outer")); // 简化写法
优化为: (propTypes, defaultProps , state 不须要给实例对象直接调用)
class Person extends React.Component { // 1. 给组件对象 设置 state 属性 state = { isLikeMe: false } // 给类添加 属性,只能 类 内部调用 // 2. 设置 props 中属性的约束条件 static propTypes = { name: PropTypes.string.isRequired // 必须传参,且 string } // 3. 设置 props 中属性的默认值 static defaultProps = { age: 18, sex: "未知" } render(){ const {name, age, sex} = this.props; return ({ <ul> <li>姓名: {name}</li> <li>年龄: {age}</li> <li>性别: {sex}</li> </ul> }) } } /**************************************/ const sun = { name: "孙悟空", age: 550, sex: "男" } // name 被 isRequired 修饰,必须传,且类型必须为 string ReactDOM.render(<Person {...sun}/>, document.getElementById("outer")); // 简化写法
refs 对象
// 组件对象 refs 保存的是 ref 关联的虚拟 DOM 元素 // refs {属性: 属性值} // refs {ref 的值: 对应的 DOM 元素对象} // refs {"left": <input>元素对象} class MyComponent extends ReactComponent { hint = ()=>{ console.log(this.refs.left.value); } handleBlur = (event)=>{ // console.log(this.refs.right.value); console.log(event.target.value); } render(){ return ({ <div> <input type="text" ref="left"/> <button onClick={this.hint}></button> <input type="text" ref="right" onBlur={this.handleBlur} /> </div> }) } } ReactDOM.render(<MyComponent/>, document.getElementById("oouter"))
ReactDOM.render(<Person name={sun.name} age={sun.age} sex={sun.sex}/>, document.getElementById("outer"));
传一个 虚拟 DOM 标签,组件.props.children
传多个 虚拟 DOM 标签,组件.props.children[{...},{...}...]
程序: 是对现实世界的模拟
class 必须用 className 代替
style 的属性值必须 {{"color":"red", "font-size": "16px"}}
1. 箭头函数的方式
2. 初始化执行 constructor() 时,bind 绑定 this 从而产生一个新的函数,指向组件对象
You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
解决:
使用 defaultValue 代替 value
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React</title> <link rel="stylesheet" type="text/css" href="./css/index.css" /> </head> <body> <div id="outer"></div> <!-- javascript 代码 --> <script src="https://cdn.bootcss.com/react/16.7.0/umd/react.development.js"></script> <script src="https://cdn.bootcss.com/react-dom/16.7.0/umd/react-dom.development.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.js"></script> <script type="text/babel"> class ButtonText extends React.Component { // 组件类 hint = ()=>{ alert("left : "+this.refs.left.value) } centerInfo = (event)=>{ this.refs.tips.innerHTML = event.target.value } handleBlur = (event)=>{ console.log("right : "+event.target.value) } render(){ return ( <div> <div> <label> <input type="text" ref="left" defaultValue="Come on!"/> </label> <label> <input type="text" ref="center" onKeyUp={this.centerInfo}/> </label> <label> <input type="text" ref="right" onBlur={this.handleBlur}/> </label> </div> <button onClick={this.hint}>Tips</button> <p ref="tips">Hello there.</p> </div> ) } } ReactDOM.render(<ButtonText/>, document.getElementById("outer")); </script> </body> </html>
问题: 在 create-react-app 以后的项目,进行 npm run build 时,发现是 用了 "/" 绝对路径,以至于找不到路径
解决: 找到 node_modules/react-scripts/config/paths.js 第 45 行修改 "/" 为 "./"
我的 './' 与 '/' 愚见,以为 './' 更好,为何官方设计是 /这样的绝对路径呢?