Javascript React子组件道具更新是否不一致?
我正在为React应用程序开发加载条组件 百分比作为整数传递,但不是过渡更新0、1、2、3、4等。。。100,道具正在更新0。。。然后直接到100 但这就是事情变得奇怪的地方 在组件的Javascript React子组件道具更新是否不一致?,javascript,reactjs,Javascript,Reactjs,我正在为React应用程序开发加载条组件 百分比作为整数传递,但不是过渡更新0、1、2、3、4等。。。100,道具正在更新0。。。然后直接到100 但这就是事情变得奇怪的地方 在组件的render()函数中,我使用console.log()输出百分比,并且控制台显示值的过渡更新(0、1、2、3等…100),但是通过{percent}渲染它仍然保持在0,然后直接跳到100 同时观察组件的React-dev工具显示它从0跳到100,但是渲染中的console.log()会遍历所有数字 以下是组件的代
render()
函数中,我使用console.log()
输出百分比,并且控制台显示值的过渡更新(0、1、2、3等…100),但是通过{percent}
渲染它仍然保持在0,然后直接跳到100
同时观察组件的React-dev工具显示它从0跳到100,但是渲染中的console.log()
会遍历所有数字
以下是组件的代码:
const Loader = ({msg, percent = null, inline = false}) => (
<div className={"loader"+(inline ? ' inline': '')}>
<i className="fa fa-refresh" />
<span>{msg}</span>
{
console.log(percent+"%") // <- this updates number by number
}
{
!isNaN(percent)
? <div className="progress-bar">
<div style={{ width: percent+"%" }} /> {/* <- this jumps from 0 right to 100 */}
</div>
: null
}
</div>
);
class ReadStory extends Component {
constructor(props) {
super(props);
this.state = {
// ...
renderTestStr: "",
storyPages: [],
pageHeight: 0,
wordCount: 0,
wordsRendered: 0
};
this.renderTest = React.createRef();
this.paginate = this.paginate.bind(this);
this.addWordAndCheckHeight = this.addWordAndCheckHeight.bind(this);
}
async componentDidMount() {
// ...
await this.paginate(storyData);
this.setState({
// ...
loading: false
});
}
paginate(storyData) {
return new Promise((resolve) => {
const {html} = storyData;
const words = html.split(' ');
const ps = window.getComputedStyle(this.renderTest.current);
const paddingY = parseFloat(ps.paddingTop) + parseFloat(ps.paddingBottom);
this.setState({
pageHeight: (this.renderTest.current.clientHeight - paddingY),
wordCount: words.length
}, async () => {
for (let i in words) {
const isLastWord = (parseInt(i) === (words.length - 1));
await this.addWordAndCheckHeight(words[i], isLastWord, i);
}
const {storyPages, renderTestStr} = this.state;
console.log(storyPages);
resolve();
});
});
}
addWordAndCheckHeight(word, isLast, i) {
return new Promise((resolve) => {
let {renderTestStr, storyPages, pageHeight} = this.state;
const renderTestReset = renderTestStr;
renderTestStr += (" " + word);
this.setState({ renderTestStr, wordsRendered: (parseInt(i) + 1) }, () => {
const ps = window.getComputedStyle(this.renderTest.current);
const paddingY = parseFloat(ps.paddingTop) + parseFloat(ps.paddingBottom);
const rtHeight = (this.renderTest.current.clientHeight - paddingY);
if (rtHeight === pageHeight && !isLast) {
resolve();
}
else if (isLast) {
storyPages = [
...storyPages,
renderTestStr
];
renderTestStr = "";
this.setState({
storyPages,
renderTestStr
}, resolve);
}
else {
storyPages = [
...storyPages,
renderTestReset
];
renderTestStr = word;
this.setState({
storyPages,
renderTestStr
}, resolve);
}
});
});
}
render() {
const {
// ...
loading,
renderTestStr,
storyPages,
wordCount,
wordsRendered
} = this.state;
const renderPercent = !isNaN(Math.floor(wordsRendered / wordCount * 100))
? Math.floor(wordsRendered / wordCount * 100)
: 0;
console.log(renderPercent);
let lrPages = [];
for (let i in storyPages) {
const isEven = (parseInt(i) % 2 === 0);
if (isEven) {
const lr = {
l: storyPages[i],
r: (storyPages[parseInt(i) + 1] || null)
};
lrPages.push(lr);
}
}
return loading
? (
<Fragment>
<Loader msg="Loading story..." percent={renderPercent} />
<div className="view read-story">
<article className="book-page render-test">
<div ref={this.renderTest}>
<p>{renderTestStr}</p>
</div>
</article>
</div>
</Fragment>
)
: (
<Fragment>
{/* ... */}
</Fragment>
);
}
}
export default withRouter(ReadStory);
它是一个大视图组件,所以我省略了许多与
加载程序组件无关的代码。paginate
和addword和checkheight
函数可能看起来很奇怪,但基本上我有需要放入可变高度
s(书中的页面)的文本,因此我需要添加每个单词并重新测量
的高度,以查看它是否超过高度限制,在这一点上,它会跳转到一个新的页面。由于这个过程在较大的故事中可能需要一些时间,所以我尝试显示一个进度条。百分比属性必须作为状态值或钩子返回值(在使用函数组件的情况下)从父组件传递。例如,您可以查看这里有一个紧密的循环:
for (let i in words) {
const isLastWord = (parseInt(i) === (words.length - 1));
await this.addWordAndCheckHeight(words[i], isLastWord, i);
}
因为addWordAndCheckHeight
不一定要等到更改的状态(以及更新的wordsrended
)在解析之前完全呈现
您可以在循环内添加一点延迟:
for (let i in words) {
const isLastWord = (parseInt(i) === (words.length - 1));
await this.addWordAndCheckHeight(words[i], isLastWord, i);
await new Promise(resolve => setTimeout(resolve, 10));
}
您也可以等到下一个组件diddupdate
触发后再进行下一次迭代,以确保它已被绘制到DOM中,并且用户可以看到它,但这会使代码有点难看。查看百分比的增量以及中是否有相同的日志行为将非常有用!isNaN
块。还有,!isNaN(null)
解析为true,因此我认为它不会按您希望的方式工作。如何更新percent
,可以显示代码吗?它的递增方式有点复杂,但我知道它的递增方式是正确的,因为控制台日志来自父组件的render()
函数也正确显示数字的增加。无论如何,我会添加代码。很高兴了解isNaN
,谢谢@dctid我想问题可能是更新是成批进行的,而且循环太紧,所以可能没有足够的时间进行更改。试着增加一个延迟,它可能会工作。嗯,好的,我会调查一下,如果我让它工作的话,我会发布。谢谢@CertainPerformance