为什么此setState调用不触发渲染?

时间:2019-10-31 13:46:26

标签: reactjs typescript

我制作了一个小的treeview组件,该组件使用结构获取json文件,并应呈现treeview。

json是正确的,构造函数上的promise已正确解析,但是在构造函数内部的setState之后未调用渲染。

我尝试阅读类似的问题,但没有成功。

export default class Tree extends Component<ITreeProps, ITreeState> {

    public constructor(props: ITreeProps, state: ITreeState) {
        super(props, state);

        Tree.GetJsonStructure(props.Path).then(response => {
            this.setState({
                data : JSON.parse(response)               
            });
            console.log(response);
          });          
    }

    public static GetJsonStructure(jsonPath: string): Promise<string>{
        return new Promise((resolve, reject) => {
          axios.get(jsonPath, { responseType: 'arraybuffer' }).then(response => {
            if (response.status !== 200) {
              // handle error
              reject("FAIL!");
            }
            var buf = new Buffer(response.data);
            //var buf = Buffer.concat(response.data);
            var paki = pako.inflate(buf);
            var decoder = new encoding.TextDecoder();
            var stringo = decoder.decode(paki);
            resolve(stringo);
          });
        });
      }

    public render(): React.ReactElement<ITreeProps> {
        console.log("RENDERINGGGG");
        console.log(this.state)

        if(!this.state || !this.state.data || this.state.data.length == 0 ){
            return <div></div>;
        }

        const data = this.state.data;

        if (!data || data.length == 0) 
            console.log("No properties set for the application");

        return (
          <div className={styles.ToolboxLinkPanel}>
              {
                  data.map(node => (
                      <TreeNode key={node.key} label={node.label} children={node.nodes} isOpen={true} ></TreeNode>
                  ))
              }
          </div>
        );
      }
}

1 个答案:

答案 0 :(得分:4)

您需要在componentDidMount内部而不是在构造函数中调用api方法:

componentDidMount() {
  Tree.GetJsonStructure(props.Path).then(response => {
    this.setState({
      data: JSON.parse(response)
    });
    console.log(response);
  });
}

关于为什么要进行api调用,official documentation进行了详细说明(强调):

  

componentDidMount()在组件被调用后立即被调用   安装(插入树中)。需要DOM的初始化   节点应该去这里。如果您需要从远程端点加载数据,   这是实例化网络请求的好地方 [...]它会触发额外的渲染,但是会在浏览器更新屏幕之前发生。