简体   繁体   English

ReactJs-将功利函数传递给模式内部的段落

[英]ReactJs - Pass a utilitarian function to a paragraph inside of a modal

I have a utilitarian funcion noMoreLonelyWords() that renders a text avoiding a single word in the end of line. 我有一个实用的noMoreLonelyWords()来呈现文本,避免在行尾出现单个单词。 Everything is working good when I import and use this function in a component. 当我在组件中导入并使用此功能时,一切工作都很好。 The problem is this funcion isn't rendering the paragraph inside the modal. 问题在于此功能未在模态内部呈现段落。 How can I solve it? 我该如何解决?

React Component: 反应组件:

import React, { Component } from 'react'
import Modal from 'react-responsive-modal';
import { noMoreLonelyWords } from './utilities/utilities.js';

class PortfolioPage extends Component {
    componentDidUpdate() {
        noMoreLonelyWords("p", 2)
    }
    render() {
        return (
            <Modal>
                <p>My text here!</p>
            </Modal>
        )

    }
}

export default PortfolioPage

noMoreLonelyWords function: Note: This function is working good. noMoreLonelyWords函数: 注意:此函数运行良好。 The body of this function doesn't matter. 该函数的主体无关紧要。 It could be anything that change the paragraph. 可能会改变段落的任何内容。 The goal is apply it into the Modal and modify its paragraph. 目标是将其应用于模式并修改其段落。

export const noMoreLonelyWords = (selector, numWords) => {      
    var elems = document.querySelectorAll(selector);
    var i;
    for (i = 0; i < elems.length; ++i) { 
      var textArray = elems[i].innerText.split(" ");      
      var lastWords = textArray.splice(-numWords, numWords).join("&nbsp;");     
      var textMinusLastWords = textArray.join(" ");
      elems[i].innerHTML = textMinusLastWords + " " + lastWords;
    }
  }

No action to change state. 无法更改状态。 So componentDidUpdate() never called. 因此componentDidUpdate()从未调用过。

componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render.

That is docs here: https://reactjs.org/docs/react-component.html#componentdidupdate 那是这里的文档: https : //reactjs.org/docs/react-component.html#componentdidupdate

You should use componentDidMount() 您应该使用componentDidMount()

componentDidMount(){
    noMoreLonelyWords("p", 2)
}

I would suggest applying your function to the text itself instead of querying the dom directly. 我建议将您的功能应用于文本本身,而不是直接查询dom。 That's not good practice especially considering the effect of the function can be achieved without direct DOM manipulation. 这不是一个好习惯,特别是考虑到无需直接进行DOM操作就可以实现功能的效果。 The reason you are accessing the DOM is to get the text of a paragraph but you don't need to as you already have that text in the render function. 您访问DOM的原因是获取段落的文本,但是您不需要,因为您已经在render函数中拥有了该文本。


  render() {
  return (
    <Modal>
      <h2><p>{noMoreLonelyWords('My text here!', 2)}</p></h2>
    </Modal>
  )
}

As @AvinKavish has mentioned, using componentDidMount() will not be effective in persisting the appearance of your component. 正如@AvinKavish提到的那样,使用componentDidMount()不能持久保留组件的外观。

You're also forcefully manipulating the DOM by changing the innerHTML of your selectors. 您还可以通过更改选择器的innerHTML来强制操作DOM。 This is very anti-pattern and defeats the purpose of using React. 这是非常反模式的,并且违反了使用React的目的。

Let's say you wanted to make your component more complex. 假设您想使组件更加复杂。 You might update the state of PortfolioPage by adding a new item, or you are connected to redux and you initialize some sort of action that brings in new props to your component. 你可能会更新statePortfolioPage通过加入新的项目,或者您已连接到redux和初始化某种action ,在带来新props到您的组件。 Your component will re-render itself with the new data, and it will revert back to its initial state, making everything that happened in componentDidMount() useless. 您的组件将使用新数据重新呈现自身,并将其恢复为初始状态,从而使componentDidMount()中发生的所有事情均无用。 componentDidMount() will not execute a second time. componentDidMount()将不会再次执行。

Also I'm sure you probably find it weird to call noMoreLonelyWords after the component has already mounted. 另外,我敢肯定在组件已挂载之后 ,调用noMoreLonelyWords很可能很奇怪。 That would mean, the paragraphs were already displayed on the screen and then they shift erratically to fit inside your modal. 这意味着段落已经显示在屏幕上,然后它们会不规则地移动以适合您的模式。

What you really should be doing is calling noMoreLonelyWords at the time of render , so your paragraphs are already adjusted correctly by the time the user sees your component. 您真正应该做的是在render时调用noMoreLonelyWords ,因此在用户看到您的组件时,您的段落已被正确调整。

To fix this, you should update noMoreLonelyWords() , instead of passing in the selector to update, just pass in the text itself. 要解决此问题,您应该更新noMoreLonelyWords() ,而不是传递选择器进行更新,而只是传递文本本身。

export const noMoreLonelyWords = (words, numWords) => {
  var textArray = words.split(" ");
  var lastWords = textArray.splice(-numWords, numWords).join("\xa0");
  var textMinusLastWords = textArray.join(" ");
  var newLine = textMinusLastWords + " " + lastWords;
  return newLine;
};

This preserves a lot of the logic that you already wrote and will also not affect other elements outside of your component, which is what you are doing when you call document.querySelectorAll to get everything on the page and manipulate it. 这将保留您已经编写的许多逻辑,并且也不会影响组件外部的其他元素,这就是您在调用document.querySelectorAll以获取页面上的所有内容并对其进行操作时所执行的操作。

Now we can bring in your updated noMoreLonelyWords() and use it by passing in any body of text you want to configure. 现在,我们可以输入更新后的noMoreLonelyWords()并通过传入要配置的任何文本体来使用它。

import React, { Component } from "react";
import Modal from "react-responsive-modal";
import { noMoreLonelyWords } from "./utilities/utilities.js";
import ReactDOM from "react-dom";

class PortfolioPage extends Component {
  state = {
    openModal: false
  };

  handleModal = () => {
    this.setState({
      openModal: !this.state.openModal
    });
  };

  createParagraphs = (paragraph, minWordsPerLine) => {
    return <p>{noMoreLonelyWords(paragraph, minWordsPerLine)}</p>;
  };

  render() {
    return (
      <div>
        {this.createParagraphs(
          "Hello friend. October arrived, spreading a damp chill over the grounds and into the castle. Madam Pomfrey, the nurse, was kept busy by a sudden spate of colds among the staff and students. Her Pepperup potion worked instantly, though it left the drinker smoking at the ears for several hours afterward. Ginny Weasley, who had been looking pale, was bullied into taking some by Percy. The steam pouring from under her vivid hair gave the impression that her whole head was on fire.",
          5
        )}
        <Modal open={this.state.openModal} onClose={this.handleModal}>
          <div>
            {this.createParagraphs(
              "Hello friend. October arrived, spreading a damp chill over the grounds and into the castle. Madam Pomfrey, the nurse, was kept busy by a sudden spate of colds among the staff and students. Her Pepperup potion worked instantly, though it left the drinker smoking at the ears for several hours afterward. Ginny Weasley, who had been looking pale, was bullied into taking some by Percy. The steam pouring from under her vivid hair gave the impression that her whole head was on fire.",
              15
            )}
          </div>
        </Modal>
        <button onClick={this.handleModal}>Open Modal</button>
      </div>
    );
  }
}

In the above we've defined a function called createParagraphs() . 在上面,我们定义了一个名为createParagraphs()的函数。 It accepts two arguments, a body of text and a number for the minimum count of words that are allowed to be on a line. 它接受两个参数,一个文本主体和一个数字 ,该数字表示允许在一行中的最少单词数。 It will call noMoreLonelyWords() and inject the output inside a <p></p> . 它将调用noMoreLonelyWords()并将输出注入<p></p>

See it in action here: https://codesandbox.io/s/modal-setting-minimum-words-per-line-hy7bc 在此处查看其运行情况: https : //codesandbox.io/s/modal-setting-minimum-words-per-line-hy7bc

We will use this function twice: 我们将两次使用此功能:

  1. Outside the Modal we call createParagraphs() pass in some text, and set the minimum count to 5. Now you see the last line has 5 words as we expected. 在Modal之外,我们调用createParagraphs()传递一些文本,并将最小计数设置为5。现在您可以看到最后一行有5个单词,符合我们的预期。
  2. Inside the Modal we call createParagraphs() pass in the same text, and set the requirement to 15. Now the modal has 15 words in the last line. 在模态内部,我们调用createParagraphs()传递相同的文本,并将需求设置为15。现在,模态在最后一行中有15个单词。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM