Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.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 - Fatal编程技术网

Javascript React子组件道具更新是否不一致?

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()会遍历所有数字 以下是组件的代

我正在为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()
会遍历所有数字

以下是组件的代码:

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