0

我正在创建 React.js Weather 项目。目前正在研究将摄氏度转换为华氏度的拨动开关。摄氏度计数是在一个组件中创建的,而切换按钮是在另一个组件中创建的。单击切换按钮时,它必须触发计数并显示它。当两者都在一个组件中创建时它工作正常,但是,我想从另一个组件触发该功能。我怎么能做到?下面是代码供参考

  1. CelToFahr.js(此处显示计数)
import React, { Component } from 'react'
import CountUp from 'react-countup';

class CeltoFahr extends Component {
    state = {
        celOn: true
    }

    render() {
        return (
            <React.Fragment>
                {/* Code for celcius to farenheit */}
                <div className="weather">
            <div className="figures">
            <div className="figuresWrap2">
                <div className="mainFigureWrap">
                    <CountUp
                        start={!this.state.celOn ? this.props.temp.cel : this.props.temp.fahr}
                        end={this.state.celOn ? this.props.temp.cel : this.props.temp.fahr}
                        duration={2}
                        >
                        {({ countUpRef, start}) => (
                            <h1 ref={countUpRef}></h1>
                        )}
                    </CountUp>    
                </div>
                </div>
                </div>
                </div>
                {/*End of Code for celcius to farenheit */}
            </React.Fragment>
        )
    }
}

export default CeltoFahr
  1. CelToFahrBtn(这里创建了切换按钮)
import React, { Component } from 'react'
import CelToFahr from './CeltoFahr'

class CelToFahrBtn extends Component {
    state = {
        celOn: true
    }

    switchCel = () => {
        this.setState({ celOn: !this.state.celOn })
    }

    render = (props) => {
        return ( 
            <div className="button" style={{display: 'inline-block'}}>
            <div className="weather">
            <div className="figures">
            <div className="figuresWrap2">
            <div className="mainFigureWrap">
                <div onClick={this.switchCel} className="CelSwitchWrap">
                    <div className={"CelSwitch" + (this.state.celOn ? "" : " transition")}>
                        <h3>C°</h3>
                        <h3>F°</h3>
                    </div>
                </div>
            </div>
            </div>
            </div>
            </div>
            </div> 
        )
    }
}

export default CelToFahrBtn

在这里,当我单击 switchCel 时,它必须触发摄氏到华氏值,反之亦然。怎么做?任何建议高度赞赏。提前致谢

4

4 回答 4

0

我会让 celToFahr 成为 celToFahrBtn 的父组件,然后通过道具传递要调用的函数

<CellToFahrBtn callback={yourfunction}/>

你还能做的是让这些组件有一个共同的父级,你将再次通过道具和回调执行执行

第三个选项是拥有一个全局状态,它将携带像 Redux 或 Reacts own Context 这样的功能。再次,您将通过道具获得所需的功能,并且您可以随时执行它。如果您的组件在 UI 和源代码中完全分离,这是最好的选择,但我认为在这种情况下情况并非如此。

https://reactjs.org/docs/context.html

这些几乎是您拥有的所有选项

于 2019-11-08T15:17:00.463 回答
0

要实现这一点,您需要提升您的状态,然后将状态和处理程序作为道具传递给所需的组件。

CeltoFahr&CelToFahrBtn然后将成为无状态组件,并依赖于从 TemperatureController 传递下来的道具

class TemperatureController extends Component {
    state = {
        celOn: true
    }

    switchCel = () => {
        this.setState({ celOn: !this.state.celOn })
    }


    render () {
       return (
         <React.Fragment>
            <CeltoFahr celOn={this.state.celOn} switchCel={this.state.switchCel} />
            <CelToFahrBtn celOn={this.state.celOn} switchCel={this.state.switchCel}/>
         </React.Fragment>
       )
    }
}

在 React Docs https://reactjs.org/docs/lifting-state-up.html上可能会更好地解释它

于 2019-11-08T15:20:26.477 回答
0

请参阅这个更简化的示例:

import React, {useState} from 'react';

const Display = ({}) => {
    const [count, setCount] = useState(0);


    return <div>
        <span>{count}</span>
        <Button countUp={() => setCount(count +1)}></Button>
    </div>
}

const Button = ({countUp}) => {
    return <button>Count up</button>
}

从父组件传递函数总是可能的。有关详细信息,请参阅提取组件

在“Thinking in React”指南中也有很好的描述。特别是第 4部分和第 5 部分

于 2019-11-08T15:23:26.353 回答
0

在 React 中,您应该始终尝试使组件尽可能地笨拙。我总是从功能组件而不是类组件开始(阅读这里为什么你应该)。

因此,我将按钮变成了一个函数:

import React from 'react';
import CelToFahr from './CeltoFahr';

function CelToFahrBtn(props) {
  return (
    <div className="button" style={{ display: 'inline-block' }}>
      <div className="weather">
        <div className="figures">
          <div className="figuresWrap2">
            <div className="mainFigureWrap">
              <div onClick={() => props.switchCel()} className="CelSwitchWrap">
                <div
                  className={'CelSwitch' + (props.celOn ? '' : ' transition')}
                >
                  <h3>C°</h3>
                  <h3>F°</h3>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default CelToFahrBtn;

你应该把逻辑放在父组件中:

import React, { Component } from 'react';
import CountUp from 'react-countup';
import CelToFahrBtn from './CelToFahrBtn';

class CeltoFahr extends Component {
  state = {
    celOn: true
  };

  switchCel = () => {
    this.setState({ celOn: !this.state.celOn });
  };

  render() {
    return (
      <>
        <div className="weather">
          <div className="figures">
            <div className="figuresWrap2">
              <div className="mainFigureWrap">
                <CelToFahrBtn switchCel={this.switchCel} celOn={celOn} />
              </div>
            </div>
          </div>
        </div>
      </>
    );
  }
}
于 2019-11-08T15:24:01.513 回答