脚手架

npm install -g create-react-app
create-react-app hello-react
cd hello-react
npm start

基于脚手架编写项目

  • 入口文件./src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css'
    import App from './components/app'
    
    ReactDOM.render(<App />, document.getElementById('root'));
  • 组件App

    import React,{Component} from 'react'
    import Logo from '../logo.svg'
    export default class App extends Component{
      render(){
        return(
          <div>
            <img src={Logo} alt=""/>
          </div>
        )
      }
    }

评论管理Demo

代码:https://github.com/changeclass/Tzk/tree/master/2020-11/14/code/react-app

入口文件

import React from 'react';
import ReactDOM from 'react-dom';

import App from './components/app/app.jsx'

ReactDOM.render(<App />, document.getElementById('root'));

我们将每个组件都单独创建一个文件夹用于存放。根组件放在./src/components/app中。我们在入口文件渲染他。

根组件

import React, { Component } from 'react'
import ComentAdd from '../coment-add/coment-add'
import ComentList from '../coment-list/coment-list'
export default class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      comments: [
        { username: 'Tom', content: 'react挺好的' },
        { username: 'Tom', content: 'react太难了' }
      ]
    }
  }
  // 添加评论
  addComent = (comment) => {
    const { comments } = this.state
    comments.unshift(comment)
    this.setState(comments)
  }
  // 删除评论
  deleteComent = (index) => {
    const { comments } = this.state
    comments.splice(index, 1)
    this.setState(comments)
  }
  render() {
    const { comments } = this.state
    return (
      <div>
        <header className='site-header jumbotron'>
          <div className='container'>
            <div className='row'>
              <div className='col-xs-12'>
                <h1>请发表对React的评论</h1>
              </div>
            </div>
          </div>
        </header>
        <div className='container'>
          <ComentAdd addComent={this.addComent} />
          <ComentList comments={comments} deleteComent={this.deleteComent} />
        </div>
      </div>
    )
  }
}

根组件的作用很简单,将子组件用到的数据(需要共享的)定义在根组件,以及操作数据的方法也定义在根组件。然后引入子组件进行渲染,并传入相关需要的数据。

添加评论组件

import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class ComentAdd extends Component {
  state = {
    username: '',
    content: ''
  }
  propsType = {
    setState: PropTypes.func.isRequired
  }
  handleNameChange = (e) => {
    const username = e.target.value
    this.setState({ username })
  }
  handleContentSubmit = (e) => {
    const content = e.target.value
    this.setState({ content })
  }
  handleSubmit = () => {
    const comment = this.state
    this.props.addComent(comment)
  }
  render() {
    const { username, content } = this.state
    return (
      <div>
        <div className='col-md-4'>
          <form className='form-horizontal'>
            <div className='form-group'>
              <label>用户名</label>
              <input
                type='text'
                className='form-control'
                placeholder='用户名'
                value={username}
                onChange={this.handleNameChange}
              />
            </div>
            <div className='form-group'>
              <label>评论内容</label>
              <textarea
                className='form-control'
                rows='6'
                placeholder='评论内容'
                value={content}
                onChange={this.handleContentSubmit}
              ></textarea>
            </div>
            <div className='form-group'>
              <div className='col-sm-offset-2 col-sm-10'>
                <button
                  type='button'
                  className='btn btn-default pull-right'
                  onClick={this.handleSubmit}
                >
                  提交
                </button>
              </div>
            </div>
          </form>
        </div>
      </div>
    )
  }
}

列表组件

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import CommentItem from '../coment-item/coment-item'
import './comentList.css'
export default class ComentList extends Component {
  static propTypes = {
    comments: PropTypes.array.isRequired,
    deleteComent: PropTypes.func.isRequired
  }

  render() {
    const { comments, deleteComent } = this.props
    const display = comments.length === 0 ? 'block' : 'none'
    console.log(display)
    return (
      <div>
        <div className='col-md-8'>
          <h3 className='reply'>评论回复:</h3>
          <h2 style={{ display }}>暂无评论,点击左侧添加评论!!!</h2>
          <ul className='list-group'>
            {comments.map((item, index) => (
              <CommentItem
                comment={item}
                key={index}
                deleteComent={deleteComent}
                index={index}
              />
            ))}
          </ul>
        </div>
      </div>
    )
  }
}

评论内容组件

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import './comentItem.css'
export default class ComentItem extends Component {
  static propTypes = {
    comment: PropTypes.object.isRequired,
    deleteComent: PropTypes.func.isRequired,
    index: PropTypes.number.isRequired
  }
  handleClick = () => {
    const { comment, deleteComent, index } = this.props
    // 提示
    if (window.confirm(`确定删除${comment.username}么?`)) {
      deleteComent(index)
    }
  }
  render() {
    const { comment } = this.props
    return (
      <li className='list-group-item'>
        <div className='handle'>
          <a href='#!' onClick={this.handleClick}>
            删除
          </a>
        </div>
        <p className='user'>
          <span>{comment.username}</span>
          <span>说:</span>
        </p>
        <p className='centence'>{comment.content}</p>
      </li>
    )
  }
}