如何在react中将状态更新为函数

时间:2019-07-08 07:17:40

标签: reactjs

我正在创建带有标签的应用程序。单击任何选项卡时,应通过修改index-big的状态来更新类this.state.addActiveTabs,但这不会发生。 我的印象是this.state.addActiveTabs为空,这就是为什么类永远都不会改变的原因,但我不明白为什么。

编辑:我认为问题出在openTabs是带有推式功能的函数,该推式创建了元素,并且无法更新该函数的推式内容。 openTabs从Tabs的兄弟组件中调用。单击菜单项时将调用它。调用时是创建选项卡,同时创建div/iframe

问题是.push创建了html,并且在函数内创建HTML之后,我无法访问它。我该怎么办?我只需要更改一个类,而不必更新整个元素或任何其他内容。

class App extends Component {
    constructor(props, context){
        super(props, context);

        ["openTabs", "removeTab", "activeTabs",].forEach((method) => {
            this[method] = this[method].bind(this);
        });
        this.displayData = [];

        this.state = {
            navigation: {
                menu: [],
            },
            tabs:{
                tabsLi: [],    
            },
            divIframe:{
                tabsDivIframe: [],
            },
            tabsiframe: '',
            showtabs: true,
            showdata: this.displayData,
            postVal: "",
            addActiveTabs: "",
        };
    }

    openTabs(e, url, iframe, trdtitle){
        //Evitar apertura automatica href
        e.preventDefault();
        //Cambiar la primera letra a mayuscula y las demas a minusculas
        function firstUppercase(string){
            return string.charAt(0).toUpperCase() + string.slice(1);
        }
        trdtitle = firstUppercase(trdtitle.toLowerCase());
        url = url.toLowerCase();
        //Cambiar el estado
        this.setState({
            showtabs: false,
        })
        //Creacion de las tabs + mostrar componentes
        if (this.state.tabs.tabsLi.includes(trdtitle) === false){                
            if(iframe  === 'si'){
                console.log(this.state.addActiveTabs);
                this.displayData.push(<div key={trdtitle.replace(/ /g, "")} id={"myTab"+trdtitle.replace(/ /g, "")} className={this.state.addIndexTabs === trdtitle ? ' index-big' : ''}><iframe title={"iframe"+trdtitle} className="iframetab" src={url}></iframe></div>);
            }
            else{
                this.displayData.push(<div key={trdtitle.replace(/ /g, "")} id={"myTab"+trdtitle.replace(/ /g, "")} className={this.state.addIndexTabs === trdtitle ? ' index-big' : ''}><div className="iframetab">{url}</div></div>);
            }
            this.setState({
                tabs: { tabsLi:[...new Set(this.state.tabs.tabsLi),trdtitle].filter(function(el) { return el; })},
                showdata : this.displayData,
                postVal : trdtitle,
            })
        }
    }

    activeTabs(value){
        this.setState({
            addActiveTabs: value, 
        })
        return () => this.setState({
           addIndexTabs: value,
        });
    }

    render(){
        return (
            <>
                    <Tabs
                        navigation={this.state.navigation}
                        textvalue={this.state.textvalue}
                        showtabs={this.state.showtabs}
                        tabs={this.state.tabs}
                        tabsLi={this.state.tabs.tabsLi}
                        divIframe={this.state.divIframe}
                        tabsDivIframe={this.state.divIframe.tabsDivIframe}
                        tabsiframe={this.state.tabsiframe}
                        showdata={this.state.showdata}
                        addActiveTabs={this.state.addActiveTabs}
                        openTabs={this.openTabs}
                        removeTab={this.removeTab}
                        displayData={this.displayData}
                        activeTabs={this.activeTabs}
                    />
            </>
        )
    }
}
class Tabs extends Component {
    constructor(props, context){
        super(props, context);

        ["showCloseTabs", "hideCloseTabs"].forEach((method) => {
            this[method] = this[method].bind(this);
        });

        this.state = {
            closeTabs: false,
        };
    }

    showCloseTabs(index, value){
        this.setState({
            closeTabs : true,
            valueTabs: value, 
        })
    }

    hideCloseTabs(){
        this.setState({
            closeTabs: false, 
        })
    }

    render(){
        return(
            <div id="content-tabs" className="tabs">
            {( this.props.showtabs)  
                ? (
                    <>
                    <div className="waiting-leads">
                        <p>Parece que todavía no hay ningún lead...</p>
                        <h3>¡Ánimo, ya llega!</h3>
                        <img src={imgDinosaurio} alt="Dinosaurio"></img>
                    </div>
                    </>
                ) : (
                    <>
                        <ul id="resizable" className="content" >
                            <LiTabs 
                                tabsLi={this.props.tabs.tabsLi}
                                closeTabs={this.state.closeTabs}
                                addActiveTabs={this.props.addActiveTabs}
                                valueTabs={this.state.valueTabs}
                                removeTab={this.props.removeTab}
                                activeTabs={this.props.activeTabs}
                                showCloseTabs={this.showCloseTabs}
                                hideCloseTabs={this.hideCloseTabs}
                            />
                        </ul>
                        <DivAndIframe
                            tabsDivIframe={this.props.divIframe.tabsDivIframe}
                            tabsiframe={this.props.tabsiframe}
                            displayData={this.props.displayData}
                        />
                    </>
            )}
            </div>
        );
    }
}

class LiTabs extends Component{
    render(){
        return(
            <>
            {this.props.tabsLi.map((value, index) =>
                <li key={index} 
                onClick={(e) => this.props.activeTabs(value)}  
                    onMouseEnter={(e) => this.props.showCloseTabs(e, value)} 
                    onMouseLeave={(e) => this.props.hideCloseTabs(e, value)} 
                    className={this.props.addActiveTabs === value ? ' active' : ''}>
                    <span>{value}</span>
                    <div onClick={this.props.removeTab.bind(this, value, index)} >
                        {this.props.closeTabs && this.props.valueTabs === value &&(
                            <Icon icon="cerrar" className='ico-cerrar'/>
                        )}
                    </div>
                </li>
            )}         
            </>
        );
    }
}

class DivAndIframe extends Component{
    render(){
        return(
            <div className="content-modules">
                {this.props.displayData}
            </div>   
        );
    }
}

1 个答案:

答案 0 :(得分:3)

利用闭包在onClick处理程序中保存制表符值的值,如下所示:

activeTabs(value){
   return () => this.setState({
      addActiveTabs: value,
   });
}

,然后在您的onClick上,将其更改为以下内容:

<li key={index} 
    onClick={(e) => this.props.activeTabs(value)} 
    className={this.props.addActiveTabs === value ? ' active' : ''}>
    <span>{value}</span>
</li>