Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 重新渲染组件两次?_Javascript_Reactjs - Fatal编程技术网

Javascript 重新渲染组件两次?

Javascript 重新渲染组件两次?,javascript,reactjs,Javascript,Reactjs,因此,我目前有一个正在运行的“待办事项”列表实现,它使用Rails作为后端API,并对前端进行响应(与axios一起发出请求)。我对Rails很熟悉,但React对我来说还是个新手 目前我有4个组件,但我关注的2个组件是List和ListItem List.js import React, { Component } from 'react'; import axios from 'axios'; import ListItem from './ListItem'; class List e

因此,我目前有一个正在运行的“待办事项”列表实现,它使用Rails作为后端API,并对前端进行响应(与axios一起发出请求)。我对Rails很熟悉,但React对我来说还是个新手

目前我有4个组件,但我关注的2个组件是
List
ListItem

List.js

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: ''
        }
    }

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

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

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

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

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

    handleChange = (e) => {
        this.setState({ newItem: e.target.value });
      }

    render() {
        return (
            <div  key={this.props.list.id}>
            <div className="card">
                <div className="card-body">
                    <h4 className="card-title">{this.props.list.title}</h4>
                    <p className="card-text">{this.props.list.description}</p>
                </div>
                <ul className="list-group list-group-flush">
                    {this.state.listItems.map( listItem => {
                        return <li className="list-group-item" key={listItem.id}><ListItem listItem={listItem} removeListItem={this.removeListItem}/></li>
                    })}
                </ul>
            </div>
                <form>
                    <div className="form-group">
                        <input className="form-control" placeholder="...." value={this.state.newItem} onChange={this.handleChange}/>
                    </div>
                        <button className="btn btn-primary btn-sm mx-1" onClick={() => this.addNewListItem(this.props.list.id, this.state.newItem)}>Add Item</button>
                        <button className="btn btn-info btn-sm mx-1" onClick={() => this.props.onUpdateList(this.props.list.id)}>Update</button>
                        <button className="btn btn-danger btn-sm mx-1" onClick={() => this.props.onRemoveList(this.props.list.id)}>Erase</button>
                </form>
            </div>

        )
    }
}

export default List;
import React, { Component } from 'react';

const ListItem = (props) =>
    <div className="list-item" >
        {props.listItem.content}
        <button className="float-right btn btn-outline-danger btn-sm" onClick={() => props.removeListItem(props.listItem.id)}>Delete</button>
    </div>

export default ListItem;
ListContainer
围绕
List
展开,但这不是我面临的问题。当我向列表中添加一个项目时,似乎会刷新整个页面(我可以看到样式消失了一秒钟)。我试图拍摄一段视频样本,但不幸的是,视频没有显示出来,因为它发生得太快了

我可以看出屏幕正在刷新,因为当我观看控制台和“保留日志”时,我看到:

VM412:1 XHR已完成加载:POST “”

然后

导航到

因此,似乎在我发布API(并更新状态)之后,我感觉它正在
addNewListItem
componentDidMount
上重新呈现。也许我错误地使用了
componentDidMount
,但是在组件挂载时引入“最新更新”项是最有意义的


奇怪的是它被重新命名了?不应该只调用一次
componentDidMount
?(我可以告诉我的控制台,在
AddNewListItem
基于控制台日志运行后,它再次被调用。或者它工作正常,这只是本地运行时出现的一些奇怪的浏览器故障?

当您在表单中放置按钮,并且没有指定默认类型时,它们将
提交
,导致您的页面重新加载为尝试调用
表单
操作。养成总是指定按钮类型的习惯-

对于实际提交表单的按钮,请将类型设置为
submit
,并使用
处理事件,并记住在其中调用
event.preventDefault()
,以停止页面重新加载。不应使用
onClick
处理提交按钮这是一种不好的做法,因为它无法访问(返回键不会提交表单)。但是
onClick
对于未提交的操作是可以的


您还应该在备忘录中包装您的
ListItem
,因为当前每个项目都在重新对账,即使只有一个项目发生了更改-
export default React.memo(ListItem)
功能等同于
React.PureComponent

当您在表单中放置按钮时,如果没有指定默认类型,它们将
提交
,导致页面在尝试调用
表单
操作时重新加载。养成始终指定按钮类型的习惯-

对于实际提交表单的按钮,请将类型设置为
submit
,并使用
处理事件,并记住在其中调用
event.preventDefault()
,以停止页面重新加载。不应使用
onClick
处理提交按钮这是一种不好的做法,因为它无法访问(返回键不会提交表单)。但是
onClick
对于未提交的操作是可以的


您还应该在备忘录中包装您的
ListItem
,因为当前每个项目都在重新对账,即使只有一个项目发生了更改-
export default React.memo(ListItem)
这在功能上相当于
React.PureComponent

React也会在setState上重新呈现@KyleCalica St Right,这就是我所期望的……但是整页刷新正在发生,这似乎很奇怪?@msmith1114我们可以间接地说是,它呈现了两次。第一次是在组件装载时,第二次是在您设置状态va时吕然后再次重播happen@msmith1114如果整个页面正在重新加载,那么它会出现一些问题。@VahidAkhtar基于导航到的
http://localhost:3000/?
我猜整个页面都在刷新。react也会在setState@KyleCalica St Right上重新呈现,这正是我所期望的……但是整个页面正在刷新,这是eems odd?@msmith1114我们可以间接地说是,它呈现了两次。第一次是在组件装载时,第二次是在设置状态值时,然后再次重新渲染happen@msmith1114如果整个页面正在重新加载,那么它会出现一些问题。@VahidAkhtar基于导航到的
http://localhost:3000/?
我猜整页都是参考的reshing.Ah!这是有道理的。我通过执行
onClick={(e)=>this.addNewListItem(e,this.props.list.id,this.state.newItem)}
并调用
e.preventDefault()来修复它
但是你的方式似乎好多了!而且我不熟悉备忘录,所以我必须仔细阅读!啊!这很有道理。我也通过执行
onClick={(e)=>this.addNewListItem(e,this.props.list.id,this.state.newItem)}
修复了它,然后调用
e.preventDefault()
但你的方式似乎好多了!而且我不熟悉备忘录,所以我必须仔细阅读!