簡體   English   中英

如何讓一個組件停用另一個組件?

[英]How to have one component deactivate the other?

我目前正在嘗試編寫一些按鈕來對列表進行排序。 當用戶與一個按鈕交互時,另一個按鈕需要無效並重置為“關閉 state”。 問題是兩者當前都可以被激活。

在此處輸入圖像描述

在此處輸入圖像描述

我最初處理這個問題的計划是讓子按鈕根據它們的道具顯示,並編寫邏輯以在父級中關閉另一個按鈕。 在我寫完之后,我發現更新孩子的道具不會導致它重新渲染,因此它永遠不會改變形狀。

相反,我編寫了按鈕如何出現在按鈕本身中的邏輯,這使我陷入了當前的困境:我無法讓一個按鈕告訴另一個按鈕自行關閉。 我處理錯了嗎? 如果是這樣,我應該怎么做?

父代碼

import React, { Component } from 'react';
import SortPlaylist from './sortPlaylist';
import Loader from './loader'
import IconButton from './iconButton'


class SortWrapper extends Component {
    state = { 
        isLoading: true,
        sortMode: "time",
        sortDirection: "linear",
    }

    async componentDidMount(){
        let plElement = <SortPlaylist origin="date" originVal="2021-01-11" sortBy="linear" loadFunc={this.updateLoad}></SortPlaylist>

        let iconButtons = [
            <IconButton key="time" sortBy="time" updateFunc={this.sortChange}/>,
            <IconButton key="votes" sortBy="votes" updateFunc={this.sortChange}/>
        ]

        this.setState({
            plElement,
            iconButtons
        })
    }

    updateLoad = () => {
        this.setState({
            isLoading: false
        })
    }
    
    sortChange = (sortBy) => {
        
    }

    render() { 
       

        return ( 
        <>  
            { this.state.isLoading ? <Loader /> : 
                <div className="sort-buttons">
                    {this.state.iconButtons}
                </div>
            }

            {this.state.plElement}
        </> 
        );
    }
}
 
export default SortWrapper;

子代碼

import React, { Component } from 'react';
import DownIcon from '../img/icons/arrow-down.svg'
import UpIcon from '../img/icons/arrow-up.svg'
import ClockIcon from '../img/icons/clock.svg'
import StarIcon from '../img/icons/star.svg'

class IconButton extends Component {
    state = {  }

    async componentDidMount(){

        let sortBy = this.props.sortBy;
        let active = this.props.active;

        this.setState({
            sortBy,
            active,
            disabled
        }, () => {
            this.updateMe(true)
        })

    }

    updateMe = (initial) => {
        let symbolElement = <></>
        let arrowElement = <></>
        let newActive = "none"
        
        if (this.state.sortBy==="time") {
            if(initial){
                symbolElement = <img className="icon-button" src={ClockIcon} alt="sort by time"/>
            }
            else if(this.state.active==="none"){
                symbolElement = <img className="icon-button active" src={ClockIcon} alt="sort by time"/>
                arrowElement = <img className="icon-button active" src={DownIcon} alt="down arrow"/>
                newActive="down"
            }
            else if(this.state.active==="down"){
                symbolElement = <img className="icon-button active" src={ClockIcon} alt="sort by time"/>
                arrowElement = <img className="icon-button active" src={UpIcon} alt="up arrow"/>
                newActive="up"
            }
            else if(this.state.active==="up"){
                symbolElement = <img className="icon-button" src={ClockIcon} alt="sort by time"/>
            }
        }

        
        if (this.state.sortBy==="votes") {
            if(initial){
                symbolElement = <img className="icon-button" src={StarIcon} alt="sort by votes"/>
            }
            else if(this.state.active==="none"){
                symbolElement = <img className="icon-button active" src={StarIcon} alt="sort by votes"/>
                arrowElement = <img className="icon-button active" src={DownIcon} alt="down arrow"/>
                newActive="down"
            }
            else if(this.state.active==="down"){
                symbolElement = <img className="icon-button active" src={StarIcon} alt="sort by votes"/>
                arrowElement = <img className="icon-button active" src={UpIcon} alt="up arrow"/>
                newActive="up"
            }
            else if(this.state.active==="up"){
                symbolElement = <img className="icon-button" src={StarIcon} alt="sort by votes"/>
            }
        }

        this.setState({
            symbolElement,
            arrowElement,
            active: newActive
        })
    }

    render() {

        return (
            <div className="icon-bundle" onClick={() => {
                this.props.updateFunc()
                this.updateMe(false)
            }}>
                {this.state.symbolElement}
                {this.state.arrowElement}
            </div>
        );
    }
}

export default IconButton;

更新#2:

我嘗試了@ppeko 的答案,將代碼更改為附件。

然而,這些按鈕根本不會改變外觀,盡管定義它們的 state 在父組件中已更改。 為什么?

父代碼

import React, { Component } from 'react';
import SortPlaylist from './sortPlaylist';
import Loader from './loader'
import IconButton from './iconButton'


class SortWrapper extends Component {
    state = { 
        isLoading: true,
        sortMode: "time",
        sortDirection: "linear",
        buttonStatus: [0, 0]
    }

    async componentDidMount(){
        let plElement = <SortPlaylist origin="date" originVal="2021-01-11" sortBy="linear" loadFunc={this.updateLoad}></SortPlaylist>

        let iconButtons = [
            <IconButton key="time" sortBy="time" updateFunc={this.sortChange} status={this.state.buttonStatus[0]}/>,
            <IconButton key="votes" sortBy="votes" updateFunc={this.sortChange} status={this.state.buttonStatus[1]}/>
        ]

        this.setState({
            plElement,
            iconButtons
        })
    }

    updateLoad = () => {
        this.setState({
            isLoading: false
        })
    }
    
    sortChange = (sortBy) => {
        console.log(sortBy + " called");
        console.log(this.state.buttonStatus);

        if(sortBy==="time"){
            this.setState({
                buttonStatus: [1,0]
            }, () => {
                console.log(this.state.buttonStatus);
            })
        }
    }

    render() { 
       

        return ( 
        <>  
            { this.state.isLoading ? <Loader /> : 
                <div className="sort-buttons">
                    {this.state.iconButtons}
                </div>
            }

            {this.state.plElement}
        </> 
        );
    }
}
 
export default SortWrapper;

子代碼

import React, { Component } from 'react';
import DownIcon from '../img/icons/arrow-down.svg'
import UpIcon from '../img/icons/arrow-up.svg'
import ClockIcon from '../img/icons/clock.svg'
import StarIcon from '../img/icons/star.svg'

class IconButton extends Component {
    state = {
        isLoading: true,
    }

    async componentDidMount(){
        const icon = this.getIcon();
        let locked = false;

        let iconCycle = [
           [<img key={this.props.sortBy} className="icon-button" src={icon} alt="sort by time"/>],
           [<img key={this.props.sortBy} className="icon-button active" src={icon} alt="sort by time"/>, 
           <img key="down" className="icon-button active" src={DownIcon} alt="down arrow"/>],
           [<img key={this.props.sortBy} className="icon-button active" src={icon} alt="sort by time"/>, 
           <img key="up" className="icon-button active" src={UpIcon} alt="up arrow"/>]
        ]

        if(this.props.status===0){
            locked = true;
        }

        this.setState({
            iconCycle,
            isLoading: false,
            locked
        })
    }

    getIcon = () => {
        if(this.props.sortBy==="time"){
            return ClockIcon
        }
        else if(this.props.sortBy==="votes"){
            return StarIcon
        }
    }

    updateMe = (initial) => {
        
    }

    render() {

        return (
            <div className="icon-bundle" onClick={() => {
                this.updateMe(false)
                this.props.updateFunc(this.props.sortBy)
            }}>
            {this.state.isLoading ? <></> : 
                this.state.locked ? this.state.iconCycle[0] :
                    this.state.iconCycle[1]
            }
            </div>
        );
    }s
}

export default IconButton;

我目前正在嘗試編寫一些按鈕來對列表進行排序。 當用戶與一個按鈕交互時,另一個按鈕需要無效並重置為“關閉 state”。 問題是兩者當前都可以被激活。

在此處輸入圖像描述

在此處輸入圖像描述

我最初處理這個問題的計划是讓子按鈕根據它們的道具顯示,並編寫邏輯以在父級中關閉另一個按鈕。 在我寫完之后,我發現更新孩子的道具不會導致它重新渲染,因此它永遠不會改變形狀。

相反,我編寫了按鈕如何出現在按鈕本身中的邏輯,這使我陷入了當前的困境:我無法讓一個按鈕告訴另一個按鈕自行關閉。 我處理錯了嗎? 如果是這樣,我應該怎么做?

父代碼

import React, { Component } from 'react';
import SortPlaylist from './sortPlaylist';
import Loader from './loader'
import IconButton from './iconButton'


class SortWrapper extends Component {
    state = { 
        isLoading: true,
        sortMode: "time",
        sortDirection: "linear",
    }

    async componentDidMount(){
        let plElement = <SortPlaylist origin="date" originVal="2021-01-11" sortBy="linear" loadFunc={this.updateLoad}></SortPlaylist>

        let iconButtons = [
            <IconButton key="time" sortBy="time" updateFunc={this.sortChange}/>,
            <IconButton key="votes" sortBy="votes" updateFunc={this.sortChange}/>
        ]

        this.setState({
            plElement,
            iconButtons
        })
    }

    updateLoad = () => {
        this.setState({
            isLoading: false
        })
    }
    
    sortChange = (sortBy) => {
        
    }

    render() { 
       

        return ( 
        <>  
            { this.state.isLoading ? <Loader /> : 
                <div className="sort-buttons">
                    {this.state.iconButtons}
                </div>
            }

            {this.state.plElement}
        </> 
        );
    }
}
 
export default SortWrapper;

子代碼

import React, { Component } from 'react';
import DownIcon from '../img/icons/arrow-down.svg'
import UpIcon from '../img/icons/arrow-up.svg'
import ClockIcon from '../img/icons/clock.svg'
import StarIcon from '../img/icons/star.svg'

class IconButton extends Component {
    state = {  }

    async componentDidMount(){

        let sortBy = this.props.sortBy;
        let active = this.props.active;

        this.setState({
            sortBy,
            active,
            disabled
        }, () => {
            this.updateMe(true)
        })

    }

    updateMe = (initial) => {
        let symbolElement = <></>
        let arrowElement = <></>
        let newActive = "none"
        
        if (this.state.sortBy==="time") {
            if(initial){
                symbolElement = <img className="icon-button" src={ClockIcon} alt="sort by time"/>
            }
            else if(this.state.active==="none"){
                symbolElement = <img className="icon-button active" src={ClockIcon} alt="sort by time"/>
                arrowElement = <img className="icon-button active" src={DownIcon} alt="down arrow"/>
                newActive="down"
            }
            else if(this.state.active==="down"){
                symbolElement = <img className="icon-button active" src={ClockIcon} alt="sort by time"/>
                arrowElement = <img className="icon-button active" src={UpIcon} alt="up arrow"/>
                newActive="up"
            }
            else if(this.state.active==="up"){
                symbolElement = <img className="icon-button" src={ClockIcon} alt="sort by time"/>
            }
        }

        
        if (this.state.sortBy==="votes") {
            if(initial){
                symbolElement = <img className="icon-button" src={StarIcon} alt="sort by votes"/>
            }
            else if(this.state.active==="none"){
                symbolElement = <img className="icon-button active" src={StarIcon} alt="sort by votes"/>
                arrowElement = <img className="icon-button active" src={DownIcon} alt="down arrow"/>
                newActive="down"
            }
            else if(this.state.active==="down"){
                symbolElement = <img className="icon-button active" src={StarIcon} alt="sort by votes"/>
                arrowElement = <img className="icon-button active" src={UpIcon} alt="up arrow"/>
                newActive="up"
            }
            else if(this.state.active==="up"){
                symbolElement = <img className="icon-button" src={StarIcon} alt="sort by votes"/>
            }
        }

        this.setState({
            symbolElement,
            arrowElement,
            active: newActive
        })
    }

    render() {

        return (
            <div className="icon-bundle" onClick={() => {
                this.props.updateFunc()
                this.updateMe(false)
            }}>
                {this.state.symbolElement}
                {this.state.arrowElement}
            </div>
        );
    }
}

export default IconButton;

更新#2:

我嘗試了@ppeko 的答案,將代碼更改為附件。

然而,這些按鈕根本不會改變外觀,盡管定義它們的 state 在父組件中已更改。 為什么?

父代碼

import React, { Component } from 'react';
import SortPlaylist from './sortPlaylist';
import Loader from './loader'
import IconButton from './iconButton'


class SortWrapper extends Component {
    state = { 
        isLoading: true,
        sortMode: "time",
        sortDirection: "linear",
        buttonStatus: [0, 0]
    }

    async componentDidMount(){
        let plElement = <SortPlaylist origin="date" originVal="2021-01-11" sortBy="linear" loadFunc={this.updateLoad}></SortPlaylist>

        let iconButtons = [
            <IconButton key="time" sortBy="time" updateFunc={this.sortChange} status={this.state.buttonStatus[0]}/>,
            <IconButton key="votes" sortBy="votes" updateFunc={this.sortChange} status={this.state.buttonStatus[1]}/>
        ]

        this.setState({
            plElement,
            iconButtons
        })
    }

    updateLoad = () => {
        this.setState({
            isLoading: false
        })
    }
    
    sortChange = (sortBy) => {
        console.log(sortBy + " called");
        console.log(this.state.buttonStatus);

        if(sortBy==="time"){
            this.setState({
                buttonStatus: [1,0]
            }, () => {
                console.log(this.state.buttonStatus);
            })
        }
    }

    render() { 
       

        return ( 
        <>  
            { this.state.isLoading ? <Loader /> : 
                <div className="sort-buttons">
                    {this.state.iconButtons}
                </div>
            }

            {this.state.plElement}
        </> 
        );
    }
}
 
export default SortWrapper;

子代碼

import React, { Component } from 'react';
import DownIcon from '../img/icons/arrow-down.svg'
import UpIcon from '../img/icons/arrow-up.svg'
import ClockIcon from '../img/icons/clock.svg'
import StarIcon from '../img/icons/star.svg'

class IconButton extends Component {
    state = {
        isLoading: true,
    }

    async componentDidMount(){
        const icon = this.getIcon();
        let locked = false;

        let iconCycle = [
           [<img key={this.props.sortBy} className="icon-button" src={icon} alt="sort by time"/>],
           [<img key={this.props.sortBy} className="icon-button active" src={icon} alt="sort by time"/>, 
           <img key="down" className="icon-button active" src={DownIcon} alt="down arrow"/>],
           [<img key={this.props.sortBy} className="icon-button active" src={icon} alt="sort by time"/>, 
           <img key="up" className="icon-button active" src={UpIcon} alt="up arrow"/>]
        ]

        if(this.props.status===0){
            locked = true;
        }

        this.setState({
            iconCycle,
            isLoading: false,
            locked
        })
    }

    getIcon = () => {
        if(this.props.sortBy==="time"){
            return ClockIcon
        }
        else if(this.props.sortBy==="votes"){
            return StarIcon
        }
    }

    updateMe = (initial) => {
        
    }

    render() {

        return (
            <div className="icon-bundle" onClick={() => {
                this.updateMe(false)
                this.props.updateFunc(this.props.sortBy)
            }}>
            {this.state.isLoading ? <></> : 
                this.state.locked ? this.state.iconCycle[0] :
                    this.state.iconCycle[1]
            }
            </div>
        );
    }s
}

export default IconButton;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM