Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.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 子组件中的输入赢得';当父组件中的道具发生更改时,t更新_Javascript_Reactjs - Fatal编程技术网

Javascript 子组件中的输入赢得';当父组件中的道具发生更改时,t更新

Javascript 子组件中的输入赢得';当父组件中的道具发生更改时,t更新,javascript,reactjs,Javascript,Reactjs,我有一个购物清单应用程序,分为以下两部分: 我实现了这两个组件:ShoppingList和:ItemDetails 还有另一个组件:ListItem,它表示一个项目行(带有编辑和删除按钮)。 ShoppinList映射到列表项数组上 我的应用程序组件获取一个初始项目数组并将其发送到ShoppingList。 每次单击特定项目行中的编辑图标时,我都会在我的应用程序组件中设置selectedItem对象,并呈现ItemDetails组件,将selectedItem传递给它,如下所示: toggle

我有一个购物清单应用程序,分为以下两部分:

我实现了这两个组件:ShoppingList和:ItemDetails 还有另一个组件:ListItem,它表示一个项目行(带有编辑和删除按钮)。 ShoppinList映射到列表项数组上

我的应用程序组件获取一个初始项目数组并将其发送到ShoppingList。 每次单击特定项目行中的编辑图标时,我都会在我的应用程序组件中设置selectedItem对象,并呈现ItemDetails组件,将selectedItem传递给它,如下所示:

toggleDetailsPanel = (itemId) => (e) => {
    this.setState((prevState, props) => {
        return {
            selectedItem: (prevState.selectedItem && prevState.selectedItem.id === itemId) ? null : this.findItemById(itemId),
        };
    });
};
在应用程序渲染功能中,我将其渲染为:

<div className={styles.details_outer_container}>
                    {this.state.selectedItem ? <ItemDetails handleSubmit={this.saveDetails} item={this.state.selectedItem}/> : null}
                </div>

{this.state.selectedItem?:null}
每当单击save按钮时,我都会在应用程序组件上运行一个函数,更新items数组中的项目(saveDetails)

现在,我希望每次单击不同项目行中的不同编辑图标时,ItemDetails组件都会呈现新值,但输入值不会更改,只有标题在呈现

我尝试了我找到的所有解决方案,包括defaultValue,或使用getValue()函数设置值,或在输入上设置一个动态键,但没有任何真正的帮助

这是我的ItemDetails文件:

import React from 'react';
import PropTypes from 'prop-types';
import { Grid, Row, Col, input, Button } from 'react-bootstrap';
import styles from './styles.css';

export default class ProductDetails extends React.Component {

    static propTypes = {
        handleSubmit: PropTypes.func.isRequired,
        item: PropTypes.any.isRequired,
    };

    state = {
        id: this.props.item.id,
        name: this.props.item.name,
        quantity: this.props.item.quantity,
        price: this.props.item.price,
        description: this.props.item.description,
    };

    // Set appropriate property in state by input name
    handleInputChange = (e) => {
        this.setState({
            [e.target.name]: e.target.value,
        });
    };

    // Submit changed item to parent component
    handleDetailsSubmit = (e) => {
        this.props.handleSubmit(this.state);
        e.preventDefault();
    };

    render() {
        const item = this.props.item;
        const itemName = item.name.toUpperCase() || '';

        return (
            <div className={styles.details_container}>
                <div className="sub_header">
                    <span>{`${itemName} DETAILS`}</span>
                </div>
                <form className={styles.form_style}>
                    <p>
                        <label>{'Quantity'}</label>
                        <input type="text" ref="quantity" name="quantity" value={this.state.quantity}  onChange={this.handleInputChange} />
                    </p>
                    <p>
                        <label>{'Price'}</label>
                        <input type="text" ref="price" name="price" value={this.state.price} onChange={this.handleInputChange}/>
                    </p>
                    <p>
                        <label>{'Description'}</label>
                        <textarea rows={2} ref="description" name="description" value={this.state.description} onChange={this.handleInputChange}/>
                    </p>
                    <div className={styles.button_div}>
                        <Button onClick={this.handleDetailsSubmit} bsStyle="primary" bsSize="small">
                            {'Save'}
                        </Button>
                    </div>
                </form>
            </`enter code here`div>

        );
    }

}
从“React”导入React;
从“道具类型”导入道具类型;
从“react bootstrap”导入{网格、行、列、输入、按钮};
从“/styles.css”导入样式;
导出默认类ProductDetails扩展React.Component{
静态类型={
handleSubmit:PropTypes.func.isRequired,
项目:PropTypes.any.isRequired,
};
状态={
id:this.props.item.id,
名称:this.props.item.name,
数量:this.props.item.quantity,
价格:this.props.item.price,
description:this.props.item.description,
};
//按输入名称在状态中设置适当的属性
handleInputChange=(e)=>{
这是我的国家({
[e.target.name]:e.target.value,
});
};
//将更改的项提交到父组件
handleDetailsSubmit=(e)=>{
this.props.handleSubmit(this.state);
e、 预防默认值();
};
render(){
const item=this.props.item;
const itemName=item.name.toUpperCase()| |“”;
返回(
{${itemName}详细信息`}

{'Quantity'}

{'Price'}

{'Description'}

{'Save'} ); } }
我知道这是React处理表单的方式,但真的不知道如何解决它。
我非常感谢您的帮助:)

ProductDetails
组件仅从
获取其初始值。从这一点上说,它是所有保持在状态。因此,您需要在
更改时重置状态

尝试添加如下内容:

componentWillReceiveProps( newProps ) {
  if ( this.props.item !== newProps.item ) {
    this.setState( {
      id: newProps.item.id,
      name: newProps.item.name,
      quantity: newProps.item.quantity,
      price: newProps.item.price,
      description: newProps.item.description,
    } )
  }
}

AppComponent中的
this.state.selectedItem
的值是否更改?是的,它会更改。在我粘贴的toggleDetailsPanel函数中,谢谢!成功了。但我认为更改child的prop应该会导致重新渲染,因此状态将通过“state={…}重新初始化初始设置。那么我错了吗?你并不是完全错了。重新渲染意味着再次运行
render
方法,因此如果在渲染方法中使用道具,它将响应更改。在实例化cla时,您的状态的初始值在类本身中设置,或者在运行一次的
构造函数
方法中设置ss(通过运行
newsomeclass()
)啊,是的,我明白了。那么将输入值绑定到组件的道具不是更好的解决方案吗?你也可以这样做。但是你可能必须更改保存方法。所以我不会说它更好,只是一种不同的方法。为什么我必须更改保存方法?在所有的输入onChange方法中,我正在更新对应的在状态中绑定属性,并且在保存时发送状态对象,该对象与输入是最新的。因此,我认为将输入绑定到道具可能更好。但我不确定这是最佳做法。