修改反应状态内的元素的属性

时间:2020-01-28 17:54:30

标签: reactjs

我有这个程序,它从我的数据库中的componentDidMount()中带出一个文章,fragmentedArticle()抓取每个单词并将其放在this.state.fragmented中,并将每个单词放在this.state的span标签中。 FragmentedTags

我以灰色文本打印文章,但是我想更改文本的样式颜色属性(每1000毫秒设置一次setTimeout),但是我不知道是否可以更改标记的属性将其保存为反应状态。

import React, { Component } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';

export default class ArticleDetails extends Component {

    constructor(props) {
        super(props);

        this.state = {
          id: '',
          title: '',
          article: '',
          date: new Date(),
          lenguages: [],
          articles: [],
          fragmented: [],
          fragmentedTags: [],
          showSpans: false,
          counterSpaces: 0,
        }

        this.deleteArticle = this.deleteArticle.bind(this);
        this.fragmentedArticle = this.fragmentedArticle.bind(this);
        this.coloredArticle = this.coloredArticle.bind(this);

    }

    componentDidMount() {

        this.setState({
            id: this.props.match.params.id 
        })

        // get individual exercise.
        axios.get('http://localhost:5000/articles/'+ this.props.match.params.id)
        .then(response => {
            this.setState({
                title: response.data.title,
                article: response.data.article,
                duration: response.data.duration,
                date: new Date(response.data.date)
            }) 
        })
        .catch(function (error) {
            console.log(error);
        })

        // get all lenguages.
        axios.get('http://localhost:5000/lenguages/')
        .then(response => {
            if (response.data.length > 0) {
            this.setState({
                lenguages: response.data.map(lenguage => lenguage.lenguage),
            })
            }
        }).catch( error => console.log(error) )
    }

    deleteArticle( id ) {
        axios.delete( 'http://localhost:5000/articles/' + id )
        .then( res => console.log( res.data ) );
            this.setState({
                articles: this.state.articles.filter( el => el._id !== id )  
            }
        )
    }

    fragmentedArticle = () => {

        let length = this.state.article.length;

        let word = [];
        let fragmentedArticle = [];
        let counter = 0;
        let p1, p2 = 0;

        for (let x = 0; x <= length; x++) {
            word[x] = this.state.article[x];
            if( this.state.article[x] === ' ' || this.state.article[x] === "\n" ){
                p2 = x;
                fragmentedArticle[counter] = word.join('').substr(p1,p2);
                p1 = p2
                p2 = 0;
                counter++;   
            }
        } 

        // we save each word
        this.setState({
            fragmented: fragmentedArticle,
            counterSpaces: counter,
            showSpans: !this.state.showSpans,
        })

        // we save each word wrapped in a span tag with a property of color grey.
        this.setState( prevState => ({
            fragmentedTags: prevState.fragmented.map( (name, index) => 
                <span key={ index } style={{color:'grey'}} >{name}</span>
            )
        })) 

    }

    coloredArticle = () => {

       console.log(this.state.fragmentedTags[0].props.style.color);
       // I see the actual value color style property of the span tag (grey) but I want to change it on green from the this.state.fragmentedTags[0] to the last word within a x period of time with the setTimeout js method.

       // this code bellow change the color but not one by one.
       this.setState( prevState => ({
            fragmentedTags: 
                // map all the elements
                prevState.fragmented.map( (name, index) =>
                    // with a delay of 1500 milliseconds
                    setTimeout(() => {
                        <span key={ index } style={{color:'green'}} >{name}</span>
                    }, 1500)
                )
            })
       )

    }

    render(props) {

        const displaySpan = this.state.showSpans ? 'inline-block' : 'none';

        const {fragmentedTags} = this.state

        return (
            <div>

                <h6>{ this.state.title }</h6>

                {/* this show/hide the article text */}
                <p onClick={ this.fragmentedArticle }>Show</p> 

                {/* I want to changed the text color one by one within a period of time (velocity, setTimeout) */}
                <p onClick={ this.coloredArticle }>Play</p> 

                {/* Show us the full article (each word wrapped in a span with its property) */}
                <div style={{ display:displaySpan }}>
                    { fragmentedTags }
                </div>

            </div>
        )
    }
}   

1 个答案:

答案 0 :(得分:0)

您不应该那样改变状态。调试应用程序变得非常困难,并且使做简单的事情变得更加困难。

下载您的文章并将其保存为状态,但是如果需要进行其他任何更改,请将其保存为状态的新部分,而不是覆盖当前状态。不过,很可能您不需要将转换保存到状态。

为回答您的问题,我将为每篇文章设置一个时间戳,一旦下载完成,我将设置一个计时器,如果经过了足够的时间,它将以新的更改重新呈现该文章。