1.state

只要组件有状态就无法使用工厂模式

1.1.初始化状态

  1. constructor (props) {
  2. super(props)
  3. this.state = {
  4. stateProp1 : value1,
  5. stateProp2 : value2
  6. }
  7. }

1.2.读取某个状态值

  1. this.state.statePropertyName

1.3. 更新状态——>组件界面更新

  1. this.setState({
  2. stateProp1 : value1,
  3. stateProp2 : value2
  4. })

1.4.案例

  1. <div id="exmaple"></div>
  2. <script src="../js/react.development.js"></script>
  3. <script src="../js/react-dom.development.js"></script>
  4. <script src="../js/babel.min.js"></script>
  5. <script type="text/babel">
  6. //定义组件类
  7. class Like extends React.Component{
  8. //给状态赋初值
  9. constructor(props){
  10. super(props)
  11. //初始化状态
  12. this.state={
  13. isLikeMe:false
  14. }
  15. //将新增方法的this强制绑定为组件对象,
  16. //bind绑定this会产生新的函数,这里的this就是组件实例对象
  17. this.handleClick=this.handleClick.bind(this)
  18. }
  19. //新添加方法:内部的this默认不是组件对象,而是underfined
  20. handleClick(){
  21. //得到状态取反
  22. const isLikeMe=!this.state.isLikeMe
  23. //更新状态
  24. this.setState({isLikeMe})
  25. }
  26. //重写组件内方法,组件内本来就有
  27. render(){
  28. //读取状态
  29. const {isLikeMe}=this.state
  30. //这里是组件对象调用这个方法
  31. return <h2 onClick={this.handleClick}>{isLikeMe?"你喜欢我":"我喜欢你"}</h2>
  32. }
  33. }
  34. //渲染标签组件
  35. ReactDOM.render(<Like/>,document.getElementById("exmaple"))

思路:首先定义组件对象,在组件对象上定义一个属性,属性值是布尔类型,用来切换文字显示的状态,在渲染阶段给标签属性绑定一个handClick事件,这里的handleClick要大写c,因为要区分跟普通的绑定事件,在事件内对定义的属性进行修改,因为这个事件是我们自己定义的,因此,这里的this是underfined,需要进行处理,使用bind对它进行操作,改变它的this指向,在把改变后的新函数,赋值给它原先的函数。

2.props

2.1.基本使用

  1. 通过在组件上定义属性,向组件内传递数据
  2. ReactDOM.render(<Person name='王苏' age={18} sex="男" />, document.getElementById("app"))
  3. 批量传递
  4. const p = { name: "wx", age: "13", sex: "女" }
  5. ReactDOM.render(<Person {...p} />, document.getElementById("app1"))

2.2.案例

  1. <div id="app"></div>
  2. <div id="app1"></div>
  3. <script src="../js/react.development.js"></script>
  4. <script src="../js/react-dom.development.js"></script>
  5. <script src="../js/babel.min.js"></script>
  6. <script src="../js/prop-types.js"></script>
  7. <script type="text/babel">
  8. class Person extends React.Component {
  9. // constructor(name, age) {
  10. // super(props)
  11. // }
  12. render() {
  13. let { name, age, sex } = this.props
  14. return (
  15. <ui>
  16. <li>我的名字{name}</li>
  17. <li>我的年龄{age + 1}</li>
  18. <li>我的性别{sex}</li>
  19. </ui>
  20. )
  21. }
  22. }
  23. //对标签属性的类型必要性进行限制
  24. Person.propTypes = {
  25. name: PropTypes.string.isRequired,
  26. age: PropTypes.number,
  27. sex: PropTypes.string
  28. }
  29. //指定默认的标签属性值
  30. Person.defaultProps = {
  31. sex: "男",
  32. age: 19
  33. }
  34. //单独页面渲染
  35. ReactDOM.render(<Person name='王苏' age={18} sex="男" />, document.getElementById("app"))
  36. //整体渲染
  37. const p = { name: "wx", age: "13", sex: "女" }
  38. ReactDOM.render(<Person {...p} />, document.getElementById("app1"))

2.3.简化props

image.png

2.4.类组件中的props

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <div id="app1"></div>
  12. <script src="../js/react.development.js"></script>
  13. <script src="../js/react-dom.development.js"></script>
  14. <script src="../js/babel.min.js"></script>
  15. <script src="../js/prop-types.js"></script>
  16. <script type="text/babel">
  17. //构造器是否接受。取决与是否希望通过this拿到props
  18. //类中的构造器能省略就省略
  19. class Person extends React.Component {
  20. constructor(props){
  21. super(props)
  22. console.log(this.props)
  23. }
  24. //static表示定义一个静态成员,该属性直接定义在类上
  25. //对标签属性的类型必要性进行限制
  26. static propTypes = {
  27. name: PropTypes.string.isRequired,
  28. age: PropTypes.number,
  29. sex: PropTypes.string
  30. }
  31. //指定默认的标签属性值
  32. static defaultProps = {
  33. sex: "男",
  34. age: 19
  35. }
  36. render() {
  37. let { name, age, sex } = this.props
  38. return (
  39. <ul>
  40. <li>我的名字{name}</li>
  41. <li>我的年龄{age+1}</li>
  42. <li>我的性别{sex}</li>
  43. </ul>
  44. )
  45. }
  46. }
  47. //单独页面渲染
  48. ReactDOM.render(<Person name='王苏'/>, document.getElementById("app"))
  49. </script>
  50. </body>
  51. </html>

2.5.函数组件使用props

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <div id="app1"></div>
  12. <script src="../js/react.development.js"></script>
  13. <script src="../js/react-dom.development.js"></script>
  14. <script src="../js/babel.min.js"></script>
  15. <script src="../js/prop-types.js"></script>
  16. <script type="text/babel">
  17. function Person(props) {
  18. const {name,age,sex}=props
  19. return (
  20. <ul>
  21. <li>我的名字{name}</li>
  22. <li>我的年龄{age + 1}</li>
  23. <li>我的性别{sex}</li>
  24. </ul>
  25. )
  26. }
  27. //单独页面渲染
  28. ReactDOM.render(<Person name='王苏' age={18} sex="男" />, document.getElementById("app"))
  29. </script>
  30. </body>
  31. </html>

3.ref

3.1字符串类型的ref

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <script src="../js/react.development.js"></script>
  12. <script src="../js/react-dom.development.js"></script>
  13. <script src="../js/babel.min.js"></script>
  14. <script src="../js/prop-types.js"></script>
  15. <script type="text/babel">
  16. class Input extends React.Component {
  17. inputHandle = () => {
  18. //通过this可以拿到refs,通过refs可以收集到虚拟dom的节点
  19. let {value}=this.refs.input1
  20. alert(value)
  21. }
  22. burHandle = () => {
  23. let {value}=this.refs.input2
  24. alert(value)
  25. }
  26. render() {
  27. return <div>
  28. <input type="text" placeholder="请输入文字" ref="input1" />
  29. <button onClick={this.inputHandle}>确定</button>
  30. <input type="text" placeholder="失去焦点弹出文字" onBlur={this.burHandle} ref="input2" />
  31. </div>
  32. }
  33. }
  34. ReactDOM.render(<Input />, document.getElementById("app"))
  35. </script>
  36. </body>
  37. </html>

3.2回调函数的ref

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <script src="../js/react.development.js"></script>
  12. <script src="../js/react-dom.development.js"></script>
  13. <script src="../js/babel.min.js"></script>
  14. <script src="../js/prop-types.js"></script>
  15. <script type="text/babel">
  16. class Input extends React.Component {
  17. inputHandle = () => {
  18. //通过this可以拿到refs,通过refs可以收集到虚拟dom的节点
  19. let { input } = this
  20. // alert(value)
  21. console.log(input.value)
  22. }
  23. inputHandle1 = () => {
  24. }
  25. //将ref的回调形式写在外面避免更新页面在次调用render时再次触发
  26. outInput = (c) => {
  27. console.log(c.value)
  28. }
  29. changeHandle=()=>{
  30. this.setState({
  31. isFlag:!this.state.isFlag
  32. })
  33. }
  34. state={
  35. isFlag:true
  36. }
  37. render() {
  38. const {isFlag}=this.state
  39. return <div>
  40. {/*通过回调的方式使用ref,页面更新会调用一次,因为render函数会再次被调用,可以将内联回调函数写在外面*/}
  41. <input type="text" placeholder="请输入文字" ref={(c) => { this.input = c }} />
  42. <button onClick={this.inputHandle}>确定</button>
  43. <input type="text" placeholder="请输入文字" ref={this.outInput} />
  44. <button onClick={this.inputHandle1}>确定1</button>
  45. <h1 ref={(c) => { this.txt = c,console.log(c) }} >今天的天气格外的{isFlag?'炎热':'凉爽'}</h1>
  46. <button onClick={this.changeHandle}>切换</button>
  47. </div>
  48. }
  49. }
  50. ReactDOM.render(<Input />, document.getElementById("app"))
  51. </script>
  52. </body>
  53. </html>

内联回调函数ref默认调用两次
image.png

3.3 createRef

React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点
首先定义一个属性,把React.createRef挂载上去

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <script src="../js/react.development.js"></script>
  12. <script src="../js/react-dom.development.js"></script>
  13. <script src="../js/babel.min.js"></script>
  14. <script src="../js/prop-types.js"></script>
  15. <script type="text/babel">
  16. class Inputs extends React.Component {
  17. inputHandle=()=>{
  18. let {current}=this.myRef
  19. console.log(current.value)
  20. }
  21. myRef=React.createRef()
  22. render() {
  23. return( <div>
  24. <input type="text" placeholder="请输入文字" ref={this.myRef} />
  25. <button onClick={this.inputHandle}>确定</button>
  26. </div>)
  27. }
  28. }
  29. ReactDOM.render(<Inputs/>, document.getElementById("app"))
  30. </script>
  31. </body>