javascript - react : How to add an array of Ids to the state object from nested objects

标签 javascript reactjs antd

我有一个带有一些文本框的表单,在另一个组件中我有一个带有行选择的表格。

当点击底部的按钮时,我应该发送我已经发送的参数,但另外在 webapi 中我应该收到一个包含所选 ID 的列表。

我的主要组件是这样的:

import React, { Component } from 'react';
import { Input} from 'antd';
import Form from '../../components/uielements/form';
import Button from '../../components/uielements/button';
import Notification from '../../components/notification';
import { adalApiFetch } from '../../adalConfig';
import   ListPageTemplatesWithSelection  from './ListPageTemplatesWithSelection';

const FormItem = Form.Item;

class CreateCommunicationSiteCollectionForm extends Component {
    constructor(props) {
        super(props);
        this.state = {Title:'',Url:'', SiteDesign:'', Description:'',Owner:'',Lcid:''};
        this.handleChangeTitle = this.handleChangeTitle.bind(this);
        this.handleValidationCommunicationSiteUrl = this.handleValidationCommunicationSiteUrl.bind(this);
        this.handleChangeCommunicationSiteUrl = this.handleChangeCommunicationSiteUrl.bind(this);
        this.handleChangeSiteDesign = this.handleChangeSiteDesign.bind(this);
        this.handleChangeDescription = this.handleChangeDescription.bind(this);
        this.handleChangeOwner = this.handleChangeOwner.bind(this);
        this.handleChangelcid = this.handleChangelcid.bind(this);

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

    handleChangeTitle(event){
        this.setState({Title: event.target.value});
    }

    handleValidationCommunicationSiteUrl(rule, value, callback){
        const form = this.props.form;
        const str = form.getFieldValue('communicationsiteurl');        
        var re = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/i;
        if (str && !str.match(re)) {
            callback('Communication site url is not correctly formated.');
        } 
        else {
            callback();
        }
    }

    handleChangeCommunicationSiteUrl(event){
        this.setState({Url: event.target.value});
    }

    handleChangeSiteDesign(event){
        this.setState({SiteDesign: event.target.value});
    }

    handleChangeDescription(event){
        this.setState({Description: event.target.value});
    }

    handleChangeOwner(event){
        this.setState({Owner: event.target.value});
    }

    handleChangelcid(event){
        this.setState({Lcid: event.target.value});
    }

    handleSubmit(e){
        e.preventDefault();
        this.props.form.validateFieldsAndScroll((err, values) => {
            if (!err) {
                let data = new FormData();
                //Append files to form data
                //data.append(

                const options = {
                  method: 'post',
                  body: JSON.stringify(
                    {
                        "Title": this.state.Title,
                        "Url": this.state.Url, 
                        "SiteDesign": this.state.SiteDesign,
                        "Description": this.state.Description,
                        "Owner": this.state.Owner,
                        "Lcid": this.state.Lcid
                    }),
                    headers: {
                            'Content-Type': 'application/json; charset=utf-8'
                    }                    
                };

                adalApiFetch(fetch, "/SiteCollection/CreateCommunicationSite", options)
                  .then(response =>{
                    if(response.status === 201){
                        Notification(
                            'success',
                            'Communication Site created',
                            ''
                            );
                     }else{
                        throw "error";
                     }
                  })
                  .catch(error => {
                    Notification(
                        'error',
                        'Site collection not created',
                        error
                        );
                    console.error(error);
                });
            }
        });      
    }

    render() {
        const { getFieldDecorator } = this.props.form;
        const formItemLayout = {
        labelCol: {
            xs: { span: 24 },
            sm: { span: 6 },
        },
        wrapperCol: {
            xs: { span: 24 },
            sm: { span: 14 },
        },
        };
        const tailFormItemLayout = {
        wrapperCol: {
            xs: {
            span: 24,
            offset: 0,
            },
            sm: {
            span: 14,
            offset: 6,
            },
        },
        };
        return (
            <Form onSubmit={this.handleSubmit}>
                <FormItem {...formItemLayout} label="Title" hasFeedback>
                {getFieldDecorator('Title', {
                    rules: [
                        {
                            required: true,
                            message: 'Please input your communication site title',
                        }
                    ]
                })(<Input name="title" id="title" onChange={this.handleChangeTitle} />)}
                </FormItem>
                <FormItem {...formItemLayout} label="Communication Site Url" hasFeedback>
                {getFieldDecorator('communicationSiteUrl', {
                    rules: [
                        {
                            required: true,
                            message: 'CommunicationSite site collection url',
                        },
                        {
                            validator: this.handleValidationCommunicationSiteUrl
                        }
                    ]
                })(<Input name="communicationsSiteUrl" id="communicationsSiteUrl" onChange={this.handleChangeCommunicationSiteUrl} />)}
                </FormItem>
                <FormItem {...formItemLayout} label="Site Design" hasFeedback>
                {getFieldDecorator('sitedesign', {
                    rules: [
                        {
                            required: true,
                            message: 'Please input your site design',
                        }
                    ]
                })(<Input name="sitedesign" id="sitedesign" onChange={this.handleChangeSiteDesign} />)}
                </FormItem>
                <FormItem {...formItemLayout} label="Description" hasFeedback>
                {getFieldDecorator('description', {
                    rules: [
                        {
                            required: true,
                            message: 'Please input your description',
                        }
                    ],
                })(<Input name="description" id="description"  onChange={this.handleChangeDescription} />)}
                </FormItem>
                <FormItem {...formItemLayout} label="Owner" hasFeedback>
                {getFieldDecorator('owner', {
                    rules: [
                        {
                            required: true,
                            message: 'Please input your owner',
                        }
                    ],
                })(<Input name="owner" id="owner"  onChange={this.handleChangeOwner} />)}
                </FormItem>
                <FormItem {...formItemLayout} label="Lcid" hasFeedback>
                {getFieldDecorator('lcid', {
                    rules: [
                        {
                            required: true,
                            message: 'Please input your lcid',
                        }
                    ],
                })(<Input name="lcid" id="lcid"  onChange={this.handleChangelcid} />)}
                </FormItem>          

                <ListPageTemplatesWithSelection />


                <FormItem {...tailFormItemLayout}>
                    <Button type="primary" htmlType="submit">
                        Create communication site
                    </Button>
                </FormItem>


            </Form>



        );
    }
}

const WrappedCreateCommunicationSiteCollectionForm = Form.create()(CreateCommunicationSiteCollectionForm);
export default WrappedCreateCommunicationSiteCollectionForm;

嵌套组件是这个

import React, { Component } from 'react';
import {  Table, Radio} from 'antd';
import { adalApiFetch } from '../../adalConfig';
import Notification from '../../components/notification';

class ListPageTemplatesWithSelection extends Component {

    constructor(props) {
        super(props);
        this.state = {
            data: []
        };
    }

    fetchData = () => {
        adalApiFetch(fetch, "/PageTemplates", {})
          .then(response => response.json())
          .then(responseJson => {
            if (!this.isCancelled) {
                const results= responseJson.map(row => ({
                    key: row.Id,
                    Name: row.Name
                  }))
              this.setState({ data: results });
            }
          })
          .catch(error => {
            console.error(error);
          });
      };


    componentDidMount(){
        this.fetchData();
    }

    render(){
        const columns = [
                {
                    title: 'Id',
                    dataIndex: 'key',
                    key: 'key',
                }, 
                {
                    title: 'Name',
                    dataIndex: 'Name',
                    key: 'Name',
                }
        ];

         // rowSelection object indicates the need for row selection
         const rowSelection = {
            onChange: (selectedRowKeys, selectedRows) => {

            },
            getCheckboxProps: record => ({
                type: Radio
            }),
        };

        return (
            <Table rowSelection={rowSelection}  columns={columns} dataSource={this.state.data} />
        );
    }
}

export default ListPageTemplatesWithSelection;

所以基本上每次选中或取消选中每行上的复选框时,我都应该在父组件状态上添加/删除 ID。

这样我就可以在按下按钮时将其发送到服务器。

但我不知道如何实现这一目标。

最佳答案

将 Prop 从 child 传递给 parent 的最佳方式是通过 lifting the state up .

因此,父组件将定义一个 handleRowSelect(ids) 函数,用于处理获取当前所选行的 ID。然后可以在状态中设置这些。

constructor(props) {
  super(props);
  this.state = {
    selectedRows: [],
    ....
  };

handleRowSelect(ids) {
  this.setState({ selectedRows: ids });
}

它将函数和 selectedRows 传递给子组件:

<ListPageTemplatesWithSelection onRowSelect={this.handleRowSelect) selectedRows={this.state.selectedRows} />

子组件将具有名为 selectedRowsonRowSelect 的属性,这将调用父组件的 handleRowSelect 函数。 :

const rowSelection = {
  selectedRowKeys: this.props.selectedRows,
  onChange: (selectedRowKeys) => {
    this.props.onRowSelect(selectedRowKeys);
  }
};

关于javascript - react : How to add an array of Ids to the state object from nested objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54774951/

相关文章:

javascript - 在数组中找到最大值(在整数集中)

javascript - Postman:如何在请求正文中使用环境变量

html - 为什么需要提供 React 构建?为什么我不能直接在浏览器中打开它?

javascript - 在 react 中放置标题时遇到问题

reactjs - 如何让 ant-design Drawer 组件宽度响应

javascript - 在 Node.js 中比较两个大文件的最佳实践

javascript - 检查单击的按钮是否具有以 jQuery 中的特定字符串开头的 ID

javascript - Reactjs:nth-​​child 的替代方案(jsx 无法正确构建 "child not defined")

javascript - 使用 Antd 上传操作将图像上传到 firebase 存储时出现问题

reactjs - React daterangepicker - 移动友好