原来的代码运行良好,但是当我改用JSX替换React.createElement时,似乎不起作用,为什么?

问题描述

我是使用 react 的新手,我想从只使用 react 转换为 JSX 语言。

代码运行良好,以下是原代码

<script>

    class MyHead extends React.Component {
        render() {
            return React.createElement("LI",null,"ITEM" + this.props.level);
        }
    }

    class MyheadList extends React.Component {
        constructor(props) {
            super(props);
            this.state = { maxLevel: props.start };
        }

        componentwillMount() {
            this.intervalID = window.setInterval(() => {
                this.setState((currentState,currentProps) => {
                    if (currentState.maxLevel > currentProps.end) {
                        return currentState;
                    } else {
                        return { maxLevel: currentState.maxLevel + 1 }
                    }
                }
                );
            },1000);
        }

        componentwillUnount() {
            window.clearInterval(this.intervalID);
        }

        render() {
            let heads = [];
            let head;
            for (let i = 1; i < this.state.maxLevel; i++) {
                head = React.createElement(MyHead,{ level: i });
                heads.push(head);
            }
            return React.createElement("UL",heads);
        }
    }

    window.addEventListener("load",() => {
        let reactElement = React.createElement(MyheadList,{ start: 1,end: 4 });
        ReactDOM.render(
            reactElement,document.body
        );
    });
</script>

以上代码运行良好,但是当我改用JSX替换React.createElement时,似乎和原来的代码逻辑结果不一样,为什么?

我只删除了所有 React.createElement 并使用 JSX 语法来替换它。此外,其他所有代码都与原始代码相同。

修改代码如下:

<script type="text/babel">

    class MyHead extends React.Component {
        render() {
            return <li>"ITEM" {this.props.level}</li>;
        }
    }

    class MyheadList extends React.Component {

        constructor(props) {
            super(props);
            this.state = { maxLevel: props.start };
        }

        componentwillMount() {
            this.intervalID = window.setInterval(() => {
                this.setState((currentState,currentProps) => {
                    if (currentState.maxLevel > currentProps.end) {
                        return currentState;
                    } else {
                        return { maxLevel: currentState.maxLevel + 1 }
                    }
                });
            },1000);
        }

        componentwillUnount() {
            window.clearInterval(this.intervalID);
        }


        render() {
            let heads = [];
            let head;
            for (let i = 1; i < this.state.maxLevel; i++) {
                head = <MyHead level={i} />;
                heads.push(head);
            }
            return <ul>{heads}</ul>;
        }
    }

    window.addEventListener("load",() => {
        let reactElement = <MyheadList start="1" end="4" />;
        ReactDOM.render(
            reactElement,document.body
        );
    });
</script>

解决方法

问题

问题似乎归结为字符串连接与数学或 javascript 类型。 startend props 是字符串值,当从 props 设置初始 maxValue 状态时,它保留字符串类型。

稍后将当前的 maxLevel 状态值与 end 属性值进行比较时,char 值在数学上计算出来是一个巧合。

console.log("1" < "2"); // true
console.log("2" < "1"); // false
console.log(1 < "2");   // true
console.log("2" < 1);   // false

maxLevel 实际上是在每个“滴答声”后附加了 1。数字和字符串之间的类型强制有点有趣,它导致连接而不是加法。

console.log(1 + 1);     // 2
console.log("1" + 1);   // "11"
console.log(1 + "1");   // "11"
console.log("1" + "1"); // "11"

解决方案

虽然我不太明白,但将 maxLevel 转换为数字类型可以解决奇怪的渲染结果。我不认为它对这个代码有很大的影响,componentWillMount 在 React v16 中基本上已被弃用,更喜欢 componentDidMount 生命周期方法。为完整的映射数组添加了一个 React 键。

constructor(props) {
  super(props);
  this.state = { maxLevel: Number(props.start) };
}

当比较两个值时,应尽量在同一类型内进行比较,因此将 end 属性值转换为数字进行比较。

if (currentState.maxLevel > Number(currentProps.end)) {

class MyHead extends React.Component {
  render() {
    return <li>"ITEM" {this.props.level}</li>;
  }
}

class MyheadList extends React.Component {
  constructor(props) {
    super(props);
    this.state = { maxLevel: Number(props.start) };
  }

  intervalID = null;

  componentDidMount() {
    this.intervalID = window.setInterval(() => {
      this.setState((currentState,currentProps) => {
        if (currentState.maxLevel > Number(currentProps.end)) {
          return currentState;
        } else {
          return { maxLevel: currentState.maxLevel + 1 };
        }
      });
    },1000);
  }

  componentWillUnount() {
    window.clearInterval(this.intervalID);
  }

  render() {
    const heads = [];
    for (let i = 1; i < this.state.maxLevel; i++) {
      heads.push(<MyHead level={i} key={i} />);
    }
    return <ul>{heads}</ul>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <MyheadList start="1" end="4" />,rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.7.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.7.0/react-dom.min.js"></script>
<div id="root"></div>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...