简单的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>
    )
  }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容