React setState不会更改状态

时间:2018-02-05 12:46:42

标签: reactjs typescript

我正在尝试从antd(antdesign)UI库中更改TreeSelect组件的值。我认为我按照他们在their help中描述的方式做了所有事情,唯一的区别是我使用的是Typescript。

  

我无法更改treeSelection函数中onChange的状态。该值始终为undefined

这是我构建的TreeBrowser,我只是在另一个文件中使用它。请注意,我导入TreeBrowser的所有其他组件都能正常工作。

TreeBrowser.tsx

import * as React from 'react';
import { TreeSelect } from "antd";

const treeData = [{
  label: 'Node1',
  value: '0-0',
  key: '0-0',
  children: [{
    label: 'Child Node1',
    value: '0-0-1',
    key: '0-0-1',
  }, {
    label: 'Child Node2',
    value: '0-0-2',
    key: '0-0-2',
  }],
}, {
  label: 'Node2',
  value: '0-1',
  key: '0-1',
}];

export interface TreeBrowserProps {};
export interface TreeBrowserState {
  treeSelection: string;
};

export class TreeBrowser extends React.Component<TreeBrowserProps, TreeBrowserState> {

  state = {
    treeSelection: undefined 
  }

  onChange = (treeSelection: string) => {
    console.log(treeSelection);  // This prints correctly the treeSelection  
    this.setState({treeSelection}, () => {
      console.log('Im never called :(');
      console.log(this.state.treeSelection); // console.log is never called
    });
  }

  render() {
    return (
      <TreeSelect
        style={{ width: 300 }}
        value={this.state.treeSelection}
        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
        treeData={treeData}

        treeDefaultExpandAll
        onChange={this.onChange}
      />
    );
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "moduleResolution": "node",
    "target": "es6",
    "jsx": "react",
    "experimentalDecorators": true,
    "sourceMap": true,
    "skipDefaultLibCheck": true,
    "allowSyntheticDefaultImports": true    
  },
  "lib": [
    "es6",
    "dom"
  ],
  "types": [
    "webpack-env",
    "aspnet-webpack-react"
  ],
  "paths": {
    // Fix "Duplicate identifier" errors caused by multiple dependencies fetching their own copies of type definitions.
    // We tell TypeScript which type definitions module to treat as the canonical one (instead of combining all of them).
    "history": [
      "./node_modules/@types/history/index"
    ],
    "redux": [
      "./node_modules/@types/redux/index"
    ],
    "react": [
      "./node_modules/@types/react/index"
    ]
  },
  "exclude": [
    "bin",
    "node_modules"
  ]

}

2 个答案:

答案 0 :(得分:1)

onChange = (treeSelection: string) => {
    console.log(treeSelection);  // This prints correctly the treeSelection  
    this.setState({treeSelection}, () => {
      console.log(this.state.treeSelection); // console.log is never called
    });
  }
This should print properly. So bacically when you used non arroe function
syntax, you are loosing the context. arrow functions persist the context from the outer scope. read more about arrow functions here 

arrow-functions

答案 1 :(得分:0)

我发现了什么是错的。我最初将treeSelection值发送到undefined,而类型为string。我将其更改为有效值0-0,这就是诀窍。也可以做treeSelection: ''

export interface TreeBrowserProps {};
export interface TreeBrowserState {
  treeSelection: string;
};

export class TreeBrowser extends React.Component<TreeBrowserProps, TreeBrowserState> {

  state = {
    treeSelection: '0-0'
  }

  onChange = (treeSelection: string) => {    
    this.setState({treeSelection});
  }

  render() {
    return (
      <TreeSelect
        style={{ width: 300 }}

        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
        treeData={treeData}
        value={this.state.treeSelection}
        treeDefaultExpandAll        
        onChange={this.onChange}
      />
    );
  }
}