提问者:小点点

在没有表单组件的情况下响应输入表单?


我正在编写一个“Todo”应用程序来学习React,这是我的第一个应用程序(它使用Rails作为后端)。目前我有两个组件处理状态,这是我遇到问题的地方。

ListContainer保存“列表”的状态,“列表”保存单个ListItems的状态。现在列表工作得很好,但是我想为我的“列表”组件添加一个简单的输入框,它可以快速地向列表中添加一个新的ListItem。目前我可以添加一个“测试”值。

一种方法是创建一个ListItemForm组件,但是只发送一个值似乎是不必要的。我更多的是一个后端的人,所以我确信有一个简单的方法,只是不明显。我的javascript也相当生锈,所以我肯定它充满了错误。

无论如何,这里是列表组件:

import React, { Component } from 'react';
import axios from 'axios';
import ListItem from './ListItem';


class List extends Component { 
    constructor(props){
        super(props)
        this.state = {
            listItems: []
        }
    }

    componentDidMount() {
        axios.get(`/api/v1/lists/${this.props.list.id}/list_items.json`)
        .then(response => {
            console.log("Getting List 'listitems'")
            console.log(response.data)
            console.log(this.state.listItems)
            this.setState({
                listItems: response.data
            })
            console.log(this.state)
        })
        .catch(error => console.log(error))
    }

    addNewListItem = (list_id, content) => {
        axios.post(`/api/v1/lists/${list_id}/list_items`, {
            content: content
          })
        .then(response => {
            console.log(response)
            const listItems = [ ...this.state.listItems, response.data ]
            this.setState({listItems})
            console.log("state of list")
            console.log(this.state)

        })
        .catch(error => {
            console.log(error)
        })
    }

    removeListItem = (listItem_id) => {
        console.log("listItem_id :" + listItem_id);
        axios.delete(`/api/v1/list_items/${listItem_id}`)
        .then(response => {
            console.log(response);
            const listItems = this.state.listItems.filter(
                listItem => listItem.id !== listItem_id
            )
            this.setState({listItems})

        })
        .catch(error => {
            console.log(error)
        })
    }

    render() {
        return (
            <div className="single-list" key={this.props.list.id}>
                <h4>{this.props.list.title}</h4>
                <p>{this.props.list.description}</p>
                {console.log(this.props.list)}
                {this.state.listItems.map( listItem => {
                    return <ListItem key={listItem.id} listItem={listItem} removeListItem={this.removeListItem}/>
                })}
                <button onClick={() => this.props.onRemoveList(this.props.list.id)}>Erase</button>
                <button onClick={() => this.props.onUpdateList(this.props.list.id)}>Update</button>
                <button onClick={() => this.addNewListItem(this.props.list.id,"test")}>Add</button>
            </div>
        )
    }
}

export default List;

我希望字段在底部,只是一个带有按钮的文本字段。或者它是简单的有一个输入和附加提交按钮和on点击处理程序发送e.target.valueaddNewListItem函数?还是我想多了?

希望输入表单在“列表”组件中而不是在“列表项”中是有意义的


共1个答案

匿名用户

您必须将输入的值置于组件的状态中,当您调用添加按钮时,传递输入的状态。

import React, { Component } from 'react';
import axios from 'axios';
import ListItem from './ListItem';


class List extends Component { 
    constructor(props){
        super(props)
        this.state = {
            listItems: [],
            newItem: ''
        }

        this.handleChange = this.handleChange.bind(this);
    }

    componentDidMount() {
        axios.get(`/api/v1/lists/${this.props.list.id}/list_items.json`)
        .then(response => {
            console.log("Getting List 'listitems'")
            console.log(response.data)
            console.log(this.state.listItems)
            this.setState({
                listItems: response.data
            })
            console.log(this.state)
        })
        .catch(error => console.log(error))
    }

    addNewListItem = (list_id, content) => {
        axios.post(`/api/v1/lists/${list_id}/list_items`, {
            content: content
          })
        .then(response => {
            console.log(response)
            const listItems = [ ...this.state.listItems, response.data ]
            this.setState({listItems})
            console.log("state of list")
            console.log(this.state)

            this.setState({
              newItem: ''
            });
        })
        .catch(error => {
            console.log(error)
        })
    }

    removeListItem = (listItem_id) => {
        console.log("listItem_id :" + listItem_id);
        axios.delete(`/api/v1/list_items/${listItem_id}`)
        .then(response => {
            console.log(response);
            const listItems = this.state.listItems.filter(
                listItem => listItem.id !== listItem_id
            )
            this.setState({listItems})

        })
        .catch(error => {
            console.log(error)
        })
    }

    handleChange (event) {
      this.setState({ newItem: event.target.value });
    }

    render() {
        return (
            <div className="single-list" key={this.props.list.id}>
                <h4>{this.props.list.title}</h4>
                <p>{this.props.list.description}</p>
                {console.log(this.props.list)}
                {this.state.listItems.map( listItem => {
                    return <ListItem key={listItem.id} listItem={listItem} removeListItem={this.removeListItem}/>
                })}
                <button onClick={() => this.props.onRemoveList(this.props.list.id)}>Erase</button>
                <button onClick={() => this.props.onUpdateList(this.props.list.id)}>Update</button>

                <input value={this.state.newItem} onChange={this.handleChange}/>
                <button onClick={() => this.addNewListItem(this.props.list.id, this.state.newItem)}>Add</button>
            </div>
        )
    }
}

export default List;