react组件化实现简易留言板

效果

在这里插入图片描述
在这里插入图片描述

实现

可以拆分为三个组件,input组件,button组件,list组件

1.input组件

input组件实现昵称的输入框和留言内容的输入框,通过判断父组件上是否传了row属性来判断是展示位单行输入框还是文本域输入框。

这两种输入框上面都有一个OnInput事件,用来获取当前输入框的值。

import React,{
    
    Fragment} from 'react'

export default function Input(props) {
    
    

    let inputValue = function(e){
    
    
    	//触发父组件上面的inputValue事件,并把e.target.value(当前输入框的值)传给父组件。
        props.inputValue(e.target.value)
    }
    
    let input = null;
    if(!props.row){
    
    
        input = <input onInput={
    
    inputValue}></input>
    }else{
    
    
        input = <textarea rows="5" cols="30" onInput={
    
    inputValue}></textarea>
    }
    return (
        <Fragment>
            {
    
    input }
        </Fragment>
    )
}

2.button组件

button组件用来实现提交按钮。

import React from 'react'

export default function Button(props) {
    
    

    let handelSubmit = function(){
    
    
    	//触发父组件上面的onSubmit事件,
        props.onSubmit()
    }
    return (
        <div>
            <button onClick={
    
    handelSubmit}>提交</button>
        </div>
    )
}

3.list组件

list组件用来实现留言内容的遍历展示。
首先判断当前要遍历的数组是否有值,然后有值的话,就遍历当前事件数组。

import React from 'react'

export default function List(props) {
    
    
    
    let comment = null;
    if(!props.data || props.data.length === 0){
    
    
        comment = <p style={
    
    {
    
    textAlign:'center'}}>还没有留言!</p>
    }else{
    
    
        comment = props.data.map((item,index) => {
    
    
            return(
                <div className="comment-item" key={
    
    index}>
                    <div className="name">
                        昵称:<span>{
    
    item.name}</span>&nbsp;&nbsp;
                        时间:<span>{
    
    item.time}</span>
                    </div>
                    <div className="content">
                        内容:{
    
    item.content}
                    </div>
                    <div className="star">
                        <span onClick={
    
    () => {
    
    
                            props.addStar(item,index)
                        }}>({
    
    item.star})</span>
                    </div>
                </div>
            )
        })
    }

    return (
        <div>
            {
    
    comment}
        </div>
    )
    
}

4.App.jsx

App.jsx是父组件。

import React, {
    
     Component } from 'react';
import Button from './Button';
import Input from './Input';
import List from './List';
import './App.css'

class App extends Component {
    
    
    constructor(){
    
    
        super();
        this.state = {
    
    
            name : '',
            content : '',
            lists : []
        }
        this.userName = this.userName.bind(this);
        this.userContent = this.userContent.bind(this);
        this.submit = this.submit.bind(this);
        this.onStar = this.onStar.bind(this)
    }


    render() {
    
    
        let {
    
    lists} = this.state;
        return (
            <div>
                {
    
    /* 留言列表 */}
                <List data={
    
    lists} addStar={
    
    this.onStar}></List>
                {
    
    /* 留言操作区 */}
                <div className="comment">
                    <div className="name">
                        <span>昵称:</span>
                        <Input inputValue={
    
    this.userName}></Input>
                    </div>
                    <div className="content">
                        <span>内容:</span>
                        <Input row  inputValue={
    
    this.userContent}></Input>
                    </div>
                    <Button onSubmit={
    
    this.submit}></Button>
                </div>
            </div>
        );
    }

    //输入昵称
    //更新视图,实现数据的双向绑定,参数为子组件上的默认参数
    userName(val){
    
    
        this.setState({
    
    
            name : val
        })
    }

    //输入姓名
    //更新视图,实现数据的双向绑定,参数为子组件上的默认参数
    userContent(val){
    
    
        this.setState({
    
    
            content : val
        })
    }

    //提交事件
    //点击提交按钮的时候,往要遍历的数组中push一个对象,把name,time,content,star都传进去。
    submit(){
    
    
        let lists = this.state.lists;
        lists.push({
    
    
            name : this.state.name,    //name为当前state对象里面的name,是输入昵称事件绑定的数据
            time : this.getTime(),      //time是调用了一个自定义函数
            content : this.state.content,     //content为当前state对象里面的content,是输入留言内容事件绑定的数据
            star : 0    //star默认值为0
        })
		//更新视图  一定要记得,不是吧值push进list就没事了,一定呀更新视图,才能调用render()函数来更新视图
        this.setState({
    
    
            lists
        })
        console.log(this.state.lists)
    }

    //点赞事件
    //参数为子组件上的默认事件,item是当前要点赞的对象,index是当前要点赞对象的下标。首先获取到当前要点赞对象的副本,然后让它的点赞数加1,然后再把当前对象删除,并把新的对象传进去。
    onStar(item,index){
    
    
        let obj = item;
        obj.star ++;

        let lists = this.state.lists;
        lists.splice(index,1,obj);
		//更新视图
        this.setState({
    
    
            lists
        })
    }

    //获取时间
    getTime(){
    
    
        let d = new Date();
        return `${
      
      d.getFullYear()}-${
      
      d.getMonth()+1}-${
      
      d.getDate()} ${
      
      d.getHours()}:${
      
      d.getMinutes()}`
    }
}

export default App;

5.index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'

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


需要注意的就是,state里面有name,content,是输入事件双向绑定的数据,以及list数组对象,是提交按钮push进去的对象,里面有留言展示区域要展示的所有内容。

猜你喜欢

转载自blog.csdn.net/qq_45021462/article/details/110009057