如何与多个React组件共享同一功能?

时间:2019-09-17 02:07:06

标签: reactjs react-hooks

我遇到的情况是我与多个React组件共享同一功能。

我有多个组成部分,它们是时间下拉列表。每当在下拉列表中选择新值时,就会正确调用onTimeChange函数,并返回所选时间。

但是,我无法知道是第一次下拉列表值还是最后一次下拉列表值被更改。理想情况下,我想根据更改的下拉列表更新state的值。

我该如何解决这个问题?

export default () => {

    const onTimeChange = (time) => {
        console.log(time);
        //change state for the dropdown changed
    }

    return (
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
         <TimeDropdown onTimeChange={onTimeChange}/>
    )


}

2 个答案:

答案 0 :(得分:2)

您可以通过在onTimeChange函数中传递索引参数并将此函数传递给多个TimeDropDown组件来实现,每个组件都会调用 带有特定索引值的onTimeChange函数,并且可以根据索引值更改状态

export default () => {

 const onTimeChange = (time, index) => {
   console.log(time);
   if (index === 'value1'){
     //changes in the state using setState
   }
   if (index === 'value2'){
     //different changes in the state using setState
   }
 }
 return (
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '1')}/>
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '2')}/>
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '3')}/>
     <TimeDropdown onTimeChange={(event) => {onTimeChange(event, '4')}/>
  )
}

答案 1 :(得分:1)

我可能会这样:

onload = function() {
        if ('speechSynthesis' in window) with(speechSynthesis) {


            var playEle = document.querySelector('#play');
            var pauseEle = document.querySelector('#pause');
            var stopEle = document.querySelector('#stop');
            var flag = false;

            playEle.addEventListener('click', onClickPlay);
            pauseEle.addEventListener('click', onClickPause);
            stopEle.addEventListener('click', onClickStop);

            function onClickPlay() {
                if(!flag){
                    flag = true;
                    utterance = new SpeechSynthesisUtterance(document.querySelector('article').textContent);
                    utterance.lang = 'zh-CN';
                    utterance.onend = function(){
                        flag = false; playEle.className = pauseEle.className = ''; stopEle.className = 'stopped';
                    };
                    playEle.className = 'played';
                    stopEle.className = '';
                    speak(utterance);
                }

                let r = setInterval(() => {
                    console.log(speechSynthesis.speaking);
                        if (!speechSynthesis.speaking) {
                            clearInterval(r);
                        } else {
                        speechSynthesis.resume();
                        }
                    }, 14000);

                 if (paused) { /* unpause/resume narration */
                    playEle.className = 'played';
                    pauseEle.className = '';
                    resume();
                } 
            }

            function onClickPause() {
                if(speaking && !paused){ /* pause narration */
                    pauseEle.className = 'paused';
                    playEle.className = '';
                    pause();
                }
            }

            function onClickStop() {
                if(speaking){ /* stop narration */
                    stopEle.className = 'stopped';
                    playEle.className = pauseEle.className = '';
                    flag = false;
                    cancel();

                }
            }

        }

        else { /* speech synthesis not supported */
            msg = document.createElement('h5');
            msg.textContent = "Detected no support for Speech Synthesis";
            msg.style.textAlign = 'center';
            msg.style.backgroundColor = 'red';
            msg.style.color = 'white';
            msg.style.marginTop = msg.style.marginBottom = 0;
            document.body.insertBefore(msg, document.querySelector('div'));
        }

    }

执行类似的操作将创建这些功能的单个实例;例如相比之下,这将创建一个NEW函数:

// render this many dropdowns
const dropdowns = 3;

function App() {
  // onTimeChange accepts two arguments
  const onTimeChange = (time, index) => {
    console.log(time, index);
    //change state for the dropdown changed
  };

  // create array from dropdowns to more easily manage number of TimeDropdowns
  return Array.from({ length: dropdowns }).map((_, i) => (
    <TimeDropdown onTimeChange={onTimeChange} key={i} iteration={i} />
  ));
}

// example dropdown values
const values = [1, 2, 3, 4, 5];

class TimeDropdown extends React.Component {
  render() {
    return (
      {/* call instance function, NOT passed/props function */}
      <select onChange={this.handleTimeChange}>
        <option />
        {values.map(value => (
          <option key={value} value={value}>
            {value}
          </option>
        ))}
      </select>
    );
  }

  handleTimeChange = e => {
    // call function passed by props
    this.props.onTimeChange(e.target.value, this.props.iteration);
  }
}

ReactDOM.render(<App />, document.getElementById("app"));

查看演示: https://codepen.io/bozdoz/pen/WNegpjG?editors=0011