【问题标题】:Display the content of the clicked item in a modal popUp在模态弹出窗口中显示单击项目的内容
【发布时间】:2019-12-26 23:12:45
【问题描述】:

我正在使用 React 创建一个应用程序,我可以在其中查看有关每个国家/地区的标志和各种信息。我正在使用 API 来获取数据,并且我已经用网格将它们全部映射了。到目前为止,这是我的代码:

class App extends React.Component{
  constructor (props){
    super (props);
    this.state={
      countries : [],
      info: ""

    }
  }

  componentDidMount(){
    axios.get(`https://restcountries.eu/rest/v2/all`)
    .then(res => {
      const data = res.data;
      console.log(data);

      this.setState({
        countries : data

      })

this.showInfo = this.showInfo.bind(this)

    })

  }

  showInfo (e) {
   console.log(e.target.key);


  }


  render() {


    return (
      <div className="container">
      {this.state.countries.map(country=>

        <Country name={country.name}
                 key={country.name} 
                 population ={country.population} 
                 region={country.region}
                 capital={country.capital}
                 flag={country.flag}
                 showInfo={this.showInfo}
                 />

      )}
      </div>
    )
  }
}

export default App;

这是我的 Country-item 组件:

const Country = ({name, population, region, capital, flag, showInfo})=>{
    return (
        <div onClick={showInfo} className="country-item">

           <div className="img">
               <img src={flag}/>
               </div> 
            <p>{name}</p>
            <p>population: {population}</p>
            <p>Region: {region}</p>
            <p>Capital: {capital}</p>

        </div>
    )
}

export default Country

到目前为止,我有这样的事情: enter image description here

现在我想单击每个国家/地区框项目并在模式弹出窗口中显示单击的数据。如果我创建一个模态并且我将映射它,当然在单击时我会将它们全部显示一次。我如何传递我单击模态组件的那个框的道具?我创建了一个函数试图捕获例如关键道具,但我没有成功。最好的策略是什么?非常感谢您的帮助

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    为每个国家/地区附加一个 onClick 处理程序。单击它时,将国家名称保存到包含组件的状态。仅使用所点击国家/地区的内容渲染模式:

    class App extends React.Component{
      constructor (props){
        super (props);
        this.state={
          countries : [],
          info: "",
          clicked: ''
        }
    
        this.countryClickHandler = e => {
          this.setState({clicked: country.name}, () => {
            window.addEventListener('click', this.closeCountryPopup)
          })
        }
        this.closeCountryPopup = e => {
          this.setState({clicked: ''}, () => {
            window.removeEventListener('click', this.closeCountryPopup)
          })
        }
      }
    
      componentDidMount(){
        axios.get(`https://restcountries.eu/rest/v2/all`)
        .then(res => {
          this.setState({
            countries : res.data
          })
        })
      }
    
      renderPopup() {
        // if the clicked flag is falsy, null, or an empty string, don't render anything
        if(!this.state.clicked || this.state.clicked === null || !this.state.clicked.length) return null
    
        // otherwise, render the only clicked country by filtering it by matching it with the string in the state
        const clickedCountry = this.state.countries.find(country => country.name === this.state.clicked)
        return (
          <div className="popup_container">
            <Country 
                name={clickedCountry.name}
                key={clickedCountry.name} 
                population ={clickedCountry.population} 
                region={clickedCountry.region}
                capital={clickedCountry.capital}
                flag={clickedCountry.flag}
              />
          </div>
        )
      }
    
    
      render() {
        return (
          <div className="container">
          {this.state.countries.map(country =>
            <div onClick={this.countryClickHandler}>
              <Country 
                name={country.name}
                key={country.name} 
                population ={country.population} 
                region={country.region}
                capital={country.capital}
                flag={country.flag}
              />
           </div>
    
          )}
          { this.renderPopup() }
          </div>
        )
      }
    }
    
    export default App;
    

    【讨论】:

      【解决方案2】:

      您的App 组件应保持应以模式显示的国家/地区的状态。更具体地说,App 组件将保存在它的 state 中,如果应显示模式以及在模式中显示哪个国家/地区。

      您传递给Country 组件的showInfo 属性应在单击国家/地区时通知App 组件。

      我创建了一个代表example on CodePen

      class App extends React.Component {
          constructor () {
                  super();
                  this.state = {
                    showModal: false,
                    selectedCountry: {},
                    countries: [
                        {name: "Germany", continent: "Europe"},
                        {name: "South Korea", continent: "Asia"},
                        {name: "New Zealnd", continent: "Australia"}
                    ]
              };
          }
      
          handleCloseModal = () => {
              this.setState({
                  showModal: false
              });
          }
      
          showInfo = (name) => {
              this.setState({
                  selectedCountry: this.state.countries.find(it => it.name===name),
                  showModal: true
              });
          }
      
          render () {
              return (
                  <div>
                      {
                          this.state.countries.map((country) => <Country 
                              name={country.name} 
                              continent={country.continent} 
                              showInfo={this.showInfo}
                            />
                          )
                      }
                      <ReactModal 
                          isOpen={this.state.showModal}
                          contentLabel={this.state.selectedCountry.name}
                      >
                          <div className="modal">
                              <div>{this.state.selectedCountry.name}</div>  
                              <div>{this.state.selectedCountry.continent}</div>  
                          </div>
                          <button onClick={this.handleCloseModal}>Close Modal</button>
                      </ReactModal>
                  </div>
              );
          }
      }
      
      const Country = (props) => {
          return (
              <div className="country" onClick={() => props.showInfo(props.name)}>
                  <div>{props.name}</div>
                  <span>-</span>
                  <div>{props.continent}</div>  
              </div>
          )
      };
      

      【讨论】:

      • 非常感谢各位的回答,两人都非常有帮助。我现在唯一的问题是,每次我点击一个项目时,我在控制台日志上总是点击之前的一个元素。例如,第一次单击从一个空对象开始。你认为是因为componentDidMount吗?也许没有 api 的例子会有所不同。
      • 我不确定我是否完全理解你。你把你的console.log放在哪里了?你能复制它并分享一些展示它的链接吗?
      • 另外,如果它帮助您解决问题,请不要忘记投票并接受答案。
      • 好吧,我实现了使模态工作,现在正在显示初始网格的相同信息。现在我想访问这个数组,但似乎我无法映射它。 ``语言:数组(1)0:{iso639_1:“ca”,iso639_2:“cat”,名称:“加泰罗尼亚语”,nativeName:“català”}长度:1``。如果我从 Api 源映射它,我可以访问对象内的该数组,而如果我从单击事件映射,他们说“语言”是未定义的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      • 2015-06-27
      相关资源
      最近更新 更多