Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.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 React组件在设置状态时不更新_Javascript_Reactjs_Setstate_Semantic Ui React - Fatal编程技术网

Javascript React组件在设置状态时不更新

Javascript React组件在设置状态时不更新,javascript,reactjs,setstate,semantic-ui-react,Javascript,Reactjs,Setstate,Semantic Ui React,我试图根据状态内部的标志切换有条件地呈现组件。看起来状态正在更新,但组件未渲染。有人能说出这是怎么回事吗renderTree函数更新状态,但不调用render import React from "react"; import CheckboxTree from "react-checkbox-tree"; import "react-checkbox-tree/lib/react-checkbox-tree.css"; import

我试图根据状态内部的标志切换有条件地呈现组件。看起来状态正在更新,但组件未渲染。有人能说出这是怎么回事吗
renderTree
函数更新状态,但不调用render

import React from "react";
import CheckboxTree from "react-checkbox-tree";
import "react-checkbox-tree/lib/react-checkbox-tree.css";
import { build } from "../data";
import { Input, Dropdown } from "semantic-ui-react";
import _ from "lodash";

class Widget extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      nodes: build(),
      checked: [],
      expanded: [],
      isDropdownExpanded: false,
      keyword: ""
    };
  }

  onCheck = checked => {
    this.setState({ checked }, () => {
      console.log(this.state.checked);
    });
  };

  onExpand = expanded => {
    this.setState({ expanded }, () => {
      console.log(this.state.expanded);
    });
  };

  renderTree = () => {
    this.setState(
      prevState => {
        return {
          ...prevState,
          isDropdownExpanded: !prevState.isDropdownExpanded
        };
      },
      () => {
        console.log(this.state);
      }
    );
  };

  onSearchInputChange = (event, data, searchedNodes) => {
    this.setState(prevState => {
      if (prevState.keyword.trim() && !data.value.trim()) {
        return {
          expanded: [],
          keyword: data.value
        };
      }
      return {
        expanded: this.getAllValuesFromNodes(searchedNodes, true),
        keyword: data.value
      };
    });
  };

  shouldComponentUpdate(nextProps, nextState) {
    if (this.state.keyword !== nextState.keyword) {
      return true;
    }
    if (!_.isEqual(this.state.checked, nextState.checked)) {
      return true;
    }
    if (_.isEqual(this.state.expanded, nextState.expanded)) {
      return false;
    }
    return true;
  }

  getAllValuesFromNodes = (nodes, firstLevel) => {
    if (firstLevel) {
      const values = [];
      for (let n of nodes) {
        values.push(n.value);
        if (n.children) {
          values.push(...this.getAllValuesFromNodes(n.children, false));
        }
      }
      return values;
    } else {
      const values = [];
      for (let n of nodes) {
        values.push(n.value);
        if (n.children) {
          values.push(...this.getAllValuesFromNodes(n.children, false));
        }
      }
      return values;
    }
  };

  keywordFilter = (nodes, keyword) => {
    let newNodes = [];
    for (let n of nodes) {
      if (n.children) {
        const nextNodes = this.keywordFilter(n.children, keyword);
        if (nextNodes.length > 0) {
          n.children = nextNodes;
        } else if (n.label.toLowerCase().includes(keyword.toLowerCase())) {
          n.children = nextNodes.length > 0 ? nextNodes : [];
        }
        if (
          nextNodes.length > 0 ||
          n.label.toLowerCase().includes(keyword.toLowerCase())
        ) {
          n.label = this.getHighlightText(n.label, keyword);
          newNodes.push(n);
        }
      } else {
        if (n.label.toLowerCase().includes(keyword.toLowerCase())) {
          n.label = this.getHighlightText(n.label, keyword);
          newNodes.push(n);
        }
      }
    }
    return newNodes;
  };

  getHighlightText = (text, keyword) => {
    const startIndex = text.indexOf(keyword);
    return startIndex !== -1 ? (
      <span>
        {text.substring(0, startIndex)}
        <span style={{ color: "red" }}>
          {text.substring(startIndex, startIndex + keyword.length)}
        </span>
        {text.substring(startIndex + keyword.length)}
      </span>
    ) : (
      <span>{text}</span>
    );
  };

  render() {
    const { checked, expanded, nodes, isDropdownExpanded } = this.state;
    let searchedNodes = this.state.keyword.trim()
      ? this.keywordFilter(_.cloneDeep(nodes), this.state.keyword)
      : nodes;
    return (
      <div>
        <Dropdown fluid selection options={[]} onClick={this.renderTree} />
        {isDropdownExpanded && (
          <div>
            <Input
              style={{ marginBottom: "20px" }}
              fluid
              icon="search"
              placeholder="Search"
              iconPosition="left"
              onChange={(event, data) => {
                this.onSearchInputChange(event, data, searchedNodes);
              }}
            />
            <CheckboxTree
              nodes={searchedNodes}
              checked={checked}
              expanded={expanded}
              onCheck={this.onCheck}
              onExpand={this.onExpand}
              showNodeIcon={true}
            />
          </div>
        )}
      </div>
    );
  }
}

export default Widget;


从“React”导入React;
从“反应复选框树”导入复选框树;
导入“react checkbox tree/lib/react checkbox tree.css”;
从“./数据”导入{build};
从“语义ui反应”导入{Input,Dropdown};
从“洛达斯”进口;
类小部件扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
节点:build(),
已勾选:[],
扩展:[],
isDropdownExpanded:false,
关键词:“
};
}
onCheck=checked=>{
this.setState({checked},()=>{
console.log(this.state.checked);
});
};
onExpand=expanded=>{
this.setState({expanded},()=>{
log(this.state.expanded);
});
};
renderTree=()=>{
这是我的国家(
prevState=>{
返回{
…国家,
isDropdownExpanded:!prevState.isDropdownExpanded
};
},
() => {
console.log(this.state);
}
);
};
onSearchInputChange=(事件、数据、搜索节点)=>{
this.setState(prevState=>{
if(prevState.keyword.trim()&&!data.value.trim()){
返回{
扩展:[],
关键词:data.value
};
}
返回{
扩展:this.getAllValuesFromNodes(searchedNodes,true),
关键词:data.value
};
});
};
shouldComponentUpdate(下一步,下一步状态){
if(this.state.keyword!==nextState.keyword){
返回true;
}
if(!\u.isEqual(this.state.checked,nextState.checked)){
返回true;
}
if(u.isEqual(this.state.expanded,nextState.expanded)){
返回false;
}
返回true;
}
getAllValuesFromNodes=(节点,第一级)=>{
如果(第一级){
常量值=[];
for(设n个节点){
值。推送(n.value);
如果(儿童){
value.push(…this.getAllValuesFromNodes(n.children,false));
}
}
返回值;
}否则{
常量值=[];
for(设n个节点){
值。推送(n.value);
如果(儿童){
value.push(…this.getAllValuesFromNodes(n.children,false));
}
}
返回值;
}
};
关键字过滤器=(节点,关键字)=>{
设newNodes=[];
for(设n个节点){
如果(儿童){
const nextNodes=this.keywordFilter(n.children,关键字);
如果(nextNodes.length>0){
n、 儿童=下一个节点;
}else if(n.label.toLowerCase().includes(关键字.toLowerCase())){
n、 children=nextNodes.length>0?nextNodes:[];
}
如果(
nextNodes.length>0||
n、 label.toLowerCase().includes(关键字.toLowerCase())
) {
n、 label=this.getHighlightText(n.label,关键字);
newNodes.push(n);
}
}否则{
if(n.label.toLowerCase().includes(关键字.toLowerCase())){
n、 label=this.getHighlightText(n.label,关键字);
newNodes.push(n);
}
}
}
返回新节点;
};
getHighlightText=(文本,关键字)=>{
const startIndex=text.indexOf(关键字);
返回startIndex!==-1(
{text.substring(0,startIndex)}
{text.substring(startIndex,startIndex+关键字.length)}
{text.substring(startIndex+关键字.length)}
) : (
{text}
);
};
render(){
const{checked,expanded,nodes,isDropdownExpanded}=this.state;
让searchedNodes=this.state.keyword.trim()
?this.keywordFilter(u.cloneDeep(节点),this.state.keyword)
:节点;
返回(
{isDropdownExpanded&&(
{
此.onSearchInputChange(事件、数据、搜索节点);
}}
/>
)}
);
}
}
导出默认窗口小部件;

Ciao,要在React中强制重新渲染,必须使用
shouldComponentUpdate(nextrops,nextState)
函数。比如:

shouldComponentUpdate(nextProps, nextState) {
  return this.state.isDropdownExpanded !== nextState.isDropdownExpanded;
}

当您更改
isDropdownExpanded
值时,将触发shouldComponentUpdate,若返回值等于true,则将重新呈现组件。工作示例(基于您的codesandbox)。

Ciao,要在React中强制重新渲染,必须使用
shouldComponentUpdate(nextrops,nextState)
函数。比如:

shouldComponentUpdate(nextProps, nextState) {
  return this.state.isDropdownExpanded !== nextState.isDropdownExpanded;
}

当您更改
isDropdownExpanded
值时,将触发shouldComponentUpdate,若返回值等于true,则将重新呈现组件。工作示例(基于您的代码沙盒)。

问题在于您的
shouldComponentUpdate
方法:

shouldComponentUpdate(nextProps, nextState) {
    if (this.state.keyword !== nextState.keyword) {
      return true;
    }
    if (!_.isEqual(this.state.checked, nextState.checked)) {
      return true;
    }
    if (_.isEqual(this.state.expanded, nextState.expanded)) {
      return false;
    }
    return true;
  }

由于
renderTree
仅更改
isDropdownExpanded
值,
shouldComponentUpdate
始终返回
false

问题在于
shouldComponentUpdate
方法:

shouldComponentUpdate(nextProps, nextState) {
    if (this.state.keyword !== nextState.keyword) {
      return true;
    }
    if (!_.isEqual(this.state.checked, nextState.checked)) {
      return true;
    }
    if (_.isEqual(this.state.expanded, nextState.expanded)) {
      return false;
    }
    return true;
  }

由于
renderTree
仅更改
isDropdownExpanded
值,
shouldComponentUpdate
始终返回
false

如果
shouldComponentUpdate
返回true,则组件将重新渲染,否则不会

在您的代码沙盒中,可以看到每次单击下拉列表时,
shouldcomponinenetupdate
对于这种情况返回false

if (_.isEqual(this.state.expanded, nextState.expanded)) {
      return false;
    }
您需要在renderTree函数中更改此变量的状态,或者需要将此条件重新写入

 if (_.isEqual(this.state.isDropdownExpanded, nextState.isDropdownExpanded)) {
      return false;
    }

如果
shouldcomponnenetupdate
返回true,则组件将重新呈现,否则不会

在您的代码沙盒中,可以看到每次单击下拉列表时,