簡體   English   中英

將狀態傳遞給其他組件的最“反應”方式

[英]The most “react” way to pass state to other components

我對React很陌生。 目前我有兩個React組件-Article.js和ControlForm.js

我在Article.js中的渲染返回是這樣的:

  return (
    <div className="article">
      {article_wrapper.map( article =>
        <div key={article.node.nid} className="article-main-display">
       <h1 className="title" dangerouslySetInnerHTML={createMarkup(article.node.title)}/>
          <div className="img-div"><img src={article.node.field_image.src} /></div>

          <ControlForm />    

          <div dangerouslySetInnerHTML={createMarkup(article.node.field_user_hsk_level)} />;
          <div className="field-name-field-chinese">
          <div dangerouslySetInnerHTML={createMarkup(article.node.chinese)} />;
                  </div>
        </div>
      )}
    </div>
  );

ControlForm.js具有多個表單元素(如果需要,我希望能夠將其全部傳遞),但這是主要的元素:

        <div className="form-item form-type-select form-group">
          <label className="control-label">Font Size</label>
          <select
            value={this.state.value}
            onChange={this.handleSizeSelect}
            id="font-size"
            className="form-control form-select"
          >
            <option value="0">Small</option>
            <option value="1">Normal</option>
            <option value="2">Large</option>
            <option value="3">XL</option>
          </select>
        </div>

我希望能夠基於更改ControlForm.js中的值在Article.js中的一個div上設置一個類。

最“反應”的方式是什么? 最好同時創建一個共同的父母(目前,他們唯一的共同父母是主要的App.js)。

抱歉,如果我不完全了解它應該如何工作,這是我的第一個React應用程序。

與組件關聯的類分別是ControlForm和withFetching。

編輯-下面的演示示例可以工作,但是在如何將其正確集成到現有代碼中時,我還有一些其他問題。 這是ControlForm的現有功能:

class ControlForm extends Component {
  constructor() {
    super();
    this.state = { toggleActive: false, sizeSelect: "0", speed: 1.3, volume: .6};
    this.onToggle = this.onToggle.bind(this);
    this.handleSpeedChange = this.handleSpeedChange.bind(this);
    this.handleVolumeChange = this.handleVolumeChange.bind(this);
    this.handleSizeSelect = this.handleSizeSelect.bind(this);
  }


  onToggle() {
    this.setState({ toggleActive: !this.state.toggleActive });
  }

    handleSizeSelect(event) {
    this.setState({ sizeSelect: event.target.value });
    this.setState({font: 'large-font'});
    parentMethod(event.target.value);
  }

  handlePlayClick(e) {
    e.preventDefault();
    voice.playButtonClick();

  }
  handlePauseClick(e) {
    e.preventDefault();
    voice.pauseButtonClick();

  }
  handleStopClick(e) {
    e.preventDefault();
    voice.stopButtonClick();

  }
  handleVolumeChange(event) {
      console.log(event.target.value);
    this.setState({ volume: event.target.value });
  }
  handleSpeedChange(event) {
      console.log(event.target.value);
    this.setState({ speed: event.target.value });
  }

文章如下所示:

const withFetching = (url) => (Comp) =>
  class WithFetching extends Component {
    constructor(props) {
      super(props);

      this.state = {
        data: [],
        isLoading: false,
        error: null,
        dynamicClassName: "parentClass"
      };
      this.changeClassName = this.changeClassName.bind(this);
    }

      changeClassName(childData) {
    this.setState({
      dynamicClassName: childData
    });
  }

    componentDidMount() {
      this.setState({ isLoading: true });

      fetch(url)
        .then(response => {
          if (response.ok) {
            return response.json();
          } else {
            throw new Error('Something went wrong ...');
          }
        })
        .then(data => this.setState({ data, isLoading: false }))
        .catch(error => this.setState({ error, isLoading: false }));
    }

    render() {
        //return "test";
      return <Comp { ...this.props } { ...this.state } />
    }
  }

function createMarkup(html) {
  return {__html: html};
}

      function changeClassName(childData) {
          console.log("GETS HERE!")
    this.setState({
      dynamicClassName: childData
    });
  }

    const Articles = ({ data, isLoading, error }) => {
        console.log(data);
        console.log(isLoading);
      const article_wrapper = data.nodes || [];

      if (error) {
        return <p>{error.message}</p>;
      }

      if (isLoading) {
        return <p>Loading ...</p>;
      }

      return (
        <div className="article">
          {article_wrapper.map( article =>
            <div key={article.node.nid} className="article-main-display">
           <h1 className="title" dangerouslySetInnerHTML={createMarkup(article.node.title)}/>
              <div className="img-div"><img src={article.node.field_image.src} /></div>

              <ControlForm parentMethod={changeClassName} />

              <div dangerouslySetInnerHTML={createMarkup(article.node.field_user_hsk_level)} />;
              <div className="field-name-field-chinese">
              <div dangerouslySetInnerHTML={createMarkup(article.node.chinese)} />;
                      </div>
            </div>
          )}
        </div>
      );
    }

    export default withFetching(API)(Articles);

抱歉,所有這些問題,我知道很多原因是由於不熟悉React-這是我嘗試在React中構建的第一件事

你想改變父母從他的孩子。

首先,您必須在Article.js中創建一個處理函數,並將其作為屬性傳遞給ControlForm.js。 <ControlForm changeDiv={this.changeDiv} />

然后,您將重點放在ControlForm.js上,只要您想發生,就只需執行作為prop changeDiv傳遞的函數,例如this.props.changeDiv()

另請參見可能的重復項: 如何在React中更新父級的狀態?

Article.js,

 class Article extends React.Component { constructor(props) { super(props); this.state = { dynamicClassName: "parentClass" } this.changeClassName = this.changeClassName.bind(this); } changeClassName(childData) { this.setState({ dynamicClassName: childData }); } // user dynamicClassName wherever u want . return ( < div className = "article" > { article_wrapper.map(article => < div key = { article.node.nid } className = "article-main-display" > < h1 className = "title" dangerouslySetInnerHTML = { createMarkup(article.node.title) } /> < div className = "img-div" > < img src = { article.node.field_image.src } /></div > < ControlForm parentMethod={this.changeClassName} / > < div dangerouslySetInnerHTML = { createMarkup(article.node.field_user_hsk_level) } />; < div className = "field-name-field-chinese" > < div dangerouslySetInnerHTML = { createMarkup(article.node.chinese) } />; < / div > < /div> ) } < /div> ); } 

在ControlForm js中,

 class ControlForm extends React.Component { constructor(props) { super(props); this.state = { } this.handleSizeSelect= this.handleSizeSelect.bind(this); } handleSizeSelect() { this.props.parentMethod(this.state.value); } render() { return ( <div className="form-item form-type-select form-group"> <label className="control-label">Font Size</label> <select value={this.state.value} onChange={this.handleSizeSelect} id="font-size" className="form-control form-select" > <option value="0">Small</option> <option value="1">Normal</option> <option value="2">Large</option> <option value="3">XL</option> </select> </div> ); } } 

您可以根據狀態有條件地呈現一個類,並且您的處理程序缺少onChange事件上的值

這是一個基於狀態演示動態更改樣式的演示

暫無
暫無

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

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