背景

隔壁 zym 共事遇到了一个问题,在编辑表格时,每输出一个字符后都会失去焦点,须要从新点击聚焦后能力持续输出,如图:



起因

归根结底,是对于 key 的问题。
原先的代码中,components 在 render 中,然而在每次 setState 后都会触发 render,因而相当于每次 components 都是一个新变量、新组件。

import "./styles.css";import React from "react";import { Table, Input } from "antd";import "antd/dist/antd.css";export default class App extends React.Component {  state = {    tableInput: "",    dataSource: [      {        name: "blueju",        password: "blueju",        type: 1      }    ]  };  handleInputChange = (e, text, index) => {    const dataSource = JSON.parse(JSON.stringify(this.state.dataSource));    dataSource[index].name = e.target.value;    this.setState({      dataSource    });  };  render() {    const components = {      table(props) {        return <table>{props.children}</table>;      }    };    return (      <div className="App">        <h1>Hello CodeSandbox</h1>        <h2>Start editing to see some magic happen!</h2>        <Table dataSource={this.state.dataSource} components={components}>          <Table.Column            dataIndex="name"            title="name"            render={(text, record, index) => {              if (record.type === 1) {                return (                  <Input                    // key={index}                    value={this.state.tableInput}                    onChange={(e) => {                      // this.handleInputChange(e, text, index);                      this.setState({                        tableInput: e.target.value                      });                    }}                  />                );              }              if (record.type === 2) {                return text;              }            }}          />        </Table>        <Input.TextArea          value={JSON.stringify(this.state.dataSource, null, 2)}          autoSize        />      </div>    );  }}

批改后:

将 components 提到组件外,当然如果不须要被其余组件共享,你也能够提到组件外部。
import "./styles.css";import React from "react";import { Table, Input } from "antd";import "antd/dist/antd.css";const components = {  table(props) {    return <table>{props.children}</table>;  }};export default class App extends React.Component {  state = {    tableInput: "",    dataSource: [      {        name: "blueju",        password: "blueju",        type: 1      }    ]  };  handleInputChange = (e, text, index) => {    const dataSource = JSON.parse(JSON.stringify(this.state.dataSource));    dataSource[index].name = e.target.value;    this.setState({      dataSource    });  };  render() {    return (      <div className="App">        <h1>Hello CodeSandbox</h1>        <h2>Start editing to see some magic happen!</h2>        <Table dataSource={this.state.dataSource} components={components}>          <Table.Column            dataIndex="name"            title="name"            render={(text, record, index) => {              if (record.type === 1) {                return (                  <Input                    // key={index}                    value={this.state.tableInput}                    onChange={(e) => {                      // this.handleInputChange(e, text, index);                      this.setState({                        tableInput: e.target.value                      });                    }}                  />                );              }              if (record.type === 2) {                return text;              }            }}          />        </Table>        <Input.TextArea          value={JSON.stringify(this.state.dataSource, null, 2)}          autoSize        />      </div>    );  }}

批改后效果图:

Github

https://github.com/blueju/BlogCodeSandBox/tree/master/input-onblur-in-antd-table