我是使用 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", null, 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>
答案 0 :(得分:2)
问题似乎归结为字符串连接与数学或 javascript 类型。 start
和 end
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>