【问题标题】:Creating Objects in Iterator with React.js使用 React.js 在迭代器中创建对象
【发布时间】:2018-11-25 15:13:23
【问题描述】:

我有一个数组

let ability = ["100", "500" , "90" , "90" , "90" , "90" , "90" , "90" , "90" , "90"]

我正在迭代器中创建对象,并希望将数组的每个值传递给“Progress Circle”的道具。所以第一个对象的宽度是 100,第二个对象的宽度是 500,依此类推。

import React, {Component} from 'react';
import ProgressCircle from './ProgressCircle';
import './App.css';

class Skills extends Component {

render(){
let skills = ["HTML", "CSS", "Swift", "PHP", "Python", "React.js", 
"Javascript", "Git", "API Integration", "Java"]
let ability = ["100", "500" , "90" , "90" , "90" , "90" , "90" , "90" , 
"90" , "90"]
let map = skills.map(function(skill, i) {
  return(
    <div key={i}>
      <h1 id="skill">{skill}</h1>
      <ProgressCircle ability={ability[i]}/>
    </div>
  );
 })
 return(
  <div className="skillsCont">
    <h1 id="skillsTitle">My Skills</h1>
    {map}
  </div>
   );
 }
 }
 export default Skills;

但是,当对象在对象的类中呈现时,在 props 中传递的值不是唯一的。当迭代器遍历数组时,它会不断更改所有对象,因此所有对象最终都具有数组中最后一个值的道具,即所有对象的宽度最终为 90

import React, {Component} from 'react';
import $ from 'jquery';
import './App.css';

class ProgressCircle extends Component {
componentDidMount() {
$('.enter').click(function() {
  setTimeout(function() {
    $('.progressFill').animate({"width": this.props.ability}, 1000);
  }.bind(this), 6000);
}.bind(this));
}
render(){
return(
  <div className="progress">
    <div className="progressFill">
    </div>
  </div>
);
} 
}

export default ProgressCircle;

知道如何解决这个问题吗?

【问题讨论】:

    标签: javascript arrays reactjs iterator components


    【解决方案1】:

    这里的问题是您正在选择带有$('.progressFill').animateALL 元素,因此,当最后一个运行时,它将使用progressFill 类更改每个元素。

    您应该使用ref 仅选择您的ProgressCircle 正在创建的元素:

    import React, {
        Component
    } from 'react';
    import $ from 'jquery';
    import './App.css';
    
    class ProgressCircle extends Component {
        constructor(props) {
            super(props);
            // create a ref to store the textInput DOM element
            this.progressFillRef = React.createRef();
        }
    
        componentDidMount() {
            $('.enter').click(function() {
                setTimeout(function() {
                    $(this.progressFillRef.current).animate({
                        "width": this.props.ability
                    }, 1000);
                }.bind(this), 6000);
            }.bind(this));
        }
        render() {
            return (
                <div className = "progress" >
                    <div className = "progressFill"ref = {this.progressFillRef} >
                    </div>
                </div>
            );
        }
    }
    
    export default ProgressCircle;
    

    因此,您应该在组件的构造函数上创建一个引用,然后在您的&lt;div&gt; 上使用该引用。当你的js运行动画时,你可以用this.myRefThatIHaveCreated.current得到实际渲染的&lt;div&gt;,然后传递给$选择器

    【讨论】:

    • 要使动画正常工作,您应该使用 react 的 ref 功能。将在答案中添加一个示例
    • 不错!那么,请您将我的答案标记为正确吗? :)
    • 嗨@StephenThomas,如果这个或任何答案已经解决了您的问题,请点击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。
    【解决方案2】:

    为简洁起见,我用材质 UI 组件替换了您的进度,以显示一个很好的设置,无需 jQuery 即可完美运行。

    其他重要的事情是将不会改变的东西保留在渲染方法之外以提高性能。

    添加 getPercentage 函数只是因为 material-ui 组件需要一个 0-100 之间的值。如果你想使用线性进度指示器,你还需要一个相对值 - 使用绝对宽度值,你会遇到很多奇怪的线条从屏幕上发出:)

    我摆脱了 id 道具。 react中唯一的选择器是关键,样式使用className。

    import React, { Component } from 'react'
    import CircularProgress from '@material-ui/core/CircularProgress';
    import './App.css';
    
    const skills = [
        "HTML", "CSS", "Swift", "PHP", "Python", "React.js", "Javascript", "Git", "API Integration", "Java"
    ]
    const ability = [
        100, 500, 90, 90, 90, 90, 90 , 90 , 90 , 90
    ]
    
    const abilityMax = 1000
    
    export function getPercentage (index) {
        const value = ability[i]
        const percentageOfMax = value / abilityMax
        return percentageOfMax * 100
    }
    
    class Skills extends Component {
        constructor(props) {
            super(props);
    
            this.renderItems = this.renderItems.bind(this);
        }
    
        renderItems(skills) {
            return(
                skills.map((skill, i) => 
                    <div key={i}>
                        <h1>{skill}</h1>
                        <CircularProgress
                            variant="determinate"
                            value={getPercentage(i)}
                        />
                    </div>
                )
            )
        }
    
        render() {
            return (
                    <div className="skillsCont">
                        <h1>My Skills</h1>
                        {this.renderItems(skills)}
                    </div>
                ) 
        }
    }
    
    export default Skills;
    

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2017-08-10
      • 2020-02-12
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2016-07-25
      • 2021-02-01
      • 2011-11-22
      相关资源
      最近更新 更多