简单的React目录结构

组件化项目的目录结构

新建一个components目录写一个componentsindex.js文件用来导出各个组件,然后写好需要的模块

并为每个模块写一个index.js文件

例如:

import React, { Component } from 'react'

export default class index extends Component {
  render() {
    return (
      <div>
        <input type="text" /><button>添加</button>
      </div>
    )
  }
}

componentsindex.js文件中引入

import React, { Component } from 'react'

export default class index extends Component {
  render() {
    return (
      <div>
        <input type="text" /><button>添加</button>
      </div>
    )
  }
}

这时就能在'App.js'中引入模块,直接使用

import React, { Component } from 'react'
import {
  TodoHeader,
  TodoInput,
  TodoList
} from './components'

export default class App extends Component {
  render() {
    return (
      <>
        {/* 多个组件组合的时候必须有一个根元素 */}
        <TodoHeader />
        <TodoInput />
        <TodoList />
      </>
    )
  }
}

import React, { Component } from 'react'
import {
  TodoHeader,
  TodoInput,
  TodoList
} from './components'

export default class App extends Component {
  render() {
    return (
      <div>
        {/* 多个组件组合的时候必须有一个根元素 */}
        <TodoHeader />
        <TodoInput />
        <TodoList />
      </div>
    )
  }
}

每个组件return的东西必须只有一个根元素

多个组件组合的时候,外层就需要一个div

但是加div会额外生成一个空的div,但有时候是需要这个dom

如果不想要这个divreact提供了一个组件fragment,用来展示空标签

import React, { Component, Fragment } from 'react'
import {
  TodoHeader,
  TodoInput,
  TodoList
} from './components'

export default class App extends Component {
  render() {
    return (
      <Fragment>
        {/* 多个组件组合的时候必须有一个根元素 */}
        <TodoHeader />
        <TodoInput />
        <TodoList />
      </Fragment>
    )
  }
}

也可以写成空标签

import React, { Component } from 'react'
import {
  TodoHeader,
  TodoInput,
  TodoList
} from './components'

export default class App extends Component {
  render() {
    return (
      <>
        {/* 多个组件组合的时候必须有一个根元素 */}
        <TodoHeader />
        <TodoInput />
        <TodoList />
      </>
    )
  }
}
  • 使用prop传递参数

    import React, { Component } from 'react'
    import {
      TodoHeader,
      TodoInput,
      TodoList
    } from './components'
    
    export default class App extends Component {
      render() {
        return (
          <>
            {/* 多个组件组合的时候必须有一个根元素 */}
            <TodoHeader 
             desc="今日事,今日毕"
            >
            {/* 传递子元素 props-children*/}
              待办事项
            </TodoHeader>
            {/* 向组件传递参数 */}
            <TodoInput btnText="Add"/>
            <TodoList />
          </>
        )
      }
    }
    
    
    • 使用函数式组件接受参数

      import React from 'react'
      import PropTypes from 'prop-types'
      // 让组件变得刚强大,更方便开发人员检查
      
      export default function TodoHeader( props) {
        console.log(props)
        return (
          <>
          <h1>
            {/* 代表的是标签里面的内容 */}
            {props.children}
          </h1>
          <h3>
            {props.desc}
          </h3>
          </>
        )
      }
      
      
    • 使用组件类接受参数

      import React, { Component } from 'react'
      import PropTypes from 'prop-types'
      export default class index extends Component {
        render() {
          return (
            <div>
              <input type="text" /><button>{this.props.btnText}</button>
            </div>
          )
        }
      }
      
      
  • 使用prop-types检测传入的参数是否符合要求
npm i prop-types --save

​ 函数式组件设置默认值

import React from 'react'
import PropTypes from 'prop-types'
// 让组件变得刚强大,更方便开发人员检查

export default function TodoHeader( props) {
  console.log(props)
  return (
    <>
    <h1>
      {/* 代表的是标签里面的内容 */}
      {props.children}
    </h1>
    <h3>
      {props.desc}
      <p>{props.x + props.y}</p>
    </h3>
    </>
  )
}

// eslint-disable-next-line react/no-typos
TodoHeader.propTypes = {
  desc: PropTypes.string,
  x: PropTypes.number.isRequired,
  y: PropTypes.number.isRequired
}

类组件设置默认值

import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class index extends Component {
  static propTypes = {
    btnText: PropTypes.string
  }
  static defaultProps = {
    // 组件默认值传了的话就使用外面的,没传就使用默认的
    btnText: "添加Todo"
  }
  render() {
    return (
      <div>
        <input type="text" /><button>{this.props.btnText}</button>
      </div>
    )
  }
}

import React, { Component } from 'react'
import {
  TodoHeader,
  TodoInput,
  TodoList
} from './components'

export default class App extends Component {
  render() {
    return (
      <>
        {/* 多个组件组合的时候必须有一个根元素 */}
        <TodoHeader desc="今日事,今日毕" x="1" y={2}>
        {/* 传递子元素 */}
          待办事项
        </TodoHeader>
        {/* 向组件传递参数 */}
        <TodoInput btnText="Add"/>
        <TodoList />
      </>
    )
  }
}

  • props默认值

    • 函数式组件设置默认值

      TodoHeader.defaultProps = {
        desc: '明天'
      }
      
    • 类组件设置默认值

        static defaultProps = {
          // 组件默认值传了的话就使用外面的,没传就使用默认的
          btnText: "添加Todo"
        }
      

state定义组件内部状态,有状态组件

第一种初始化state的方式

```js
 state = {
    title: '待办事项列表1'
  }
```

第二种初始化state的方式

```js
  constructor() {
    super()
    this.state = {
      title: '待办事项列表'
    }
  }
```

16.8之前函数式组件没有this,也没有state
import React, { Component } from 'react'
import {
  TodoHeader,
  TodoInput,
  TodoList
} from './components'

export default class App extends Component {
  // state = {
  //   title: '待办事项列表1',
  // }

  constructor() {
    super()
    this.state = {
      title: '待办事项列表',
      desc:'今日事,今日毕',
      article: '<div>jiagsgsg</div>',
      todos : [{
        id: 1,
        title: '学习',
        isCompleted: 'false'
      },{
        id: 2,
        title: '吃饭',
        isCompleted: 'true'
      }]
    }
  }
  render() {
    return (
      <>
        {
          <div dangerouslySetInnerHTML = {{__html:this.state.article}}/>
        }
        {
          this.state.todos.map(todo => {
            return <div key="todo.id">{todo.title}</div>
          })
        }
      </>
    )
  }
}

import React, { Component } from 'react'
import TodoItem from './TodoItem'
export default class TodoList extends Component {
  render() {
    console.log(this.props)
    return (
      <ul>
        {
          this.props.todos.map(todo => {
            return(
              // <TodoItem
              // key={todo.id}
              // id={todo.id}
              // title={todo.title}
              // isCompleted={todo.isCompleted}
              // />
              //使用对象展开的方法在这里就能取到更新的数据
              <TodoItem
                key={todo.id}
                {...todo}
              />
            )
          })
        }
      </ul>
    )
  }
}

import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class index extends Component {
  static propTypes = {
    btnText: PropTypes.string
  }
  static defaultProps = {
    // 组件默认值传了的话就使用外面的,没传就使用默认的
    btnText: "添加Todo"
  }
  constructor () {
    super()
    this.state = {
      inputValue: ''
    }
  }
  handleInputChange = (e) => {
    this.setState({
      inputValue:e.currentTarget.value
    })
  }
  render() {
    return (
      <div>
        <input 
        type="text" 
        value={this.state.inputValue}
        onChange={this.handleInputChange}
        />
        <button>{this.props.btnText}</button>
      </div>
    )
  }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容