jjzjj

javascript - 将 AJAX 结果作为 props 传递给子组件

coder 2024-05-17 原文

我正在尝试使用 React 创建博客。在我的主要 ReactBlog 组件中,我正在对节点服务器执行 AJAX 调用以返回一组帖子。我想将此发布数据作为 Prop 传递给不同的组件。

特别是,我有一个名为 PostViewer 的组件,它将显示帖子信息。我希望它默认显示通过 Prop 从其父级传递过来的帖子,否则显示通过状态调用设置的数据。

目前,我的代码的相关部分如下所示。

var ReactBlog = React.createClass({
  getInitialState: function() {
    return {
      posts: []
    };
  },
  componentDidMount: function() {
    $.get(this.props.url, function(data) {
      if (this.isMounted()) {
        this.setState({
          posts: data
        });
      }
    }.bind(this));
  },
  render: function() {
    var latestPost = this.state.posts[0];
    return (
      <div className="layout">
        <div className="layout layout-sidebar">
          <PostList posts={this.state.posts}/>
        </div>
        <div className="layout layout-content">
          <PostViewer post={latestPost}/>
        </div>
      </div>
    )
  }
});

和子组件:

var PostViewer = React.createClass({
  getInitialState: function() {
    return {
      post: this.props.post
    }
  },
  render: function() {
    /* handle check for initial load which doesn't include prop data yet */
    if (this.state.post) {
      return (
        <div>
          {this.state.post.title}
        </div>
      )
    }
    return (
      <div/>
    )
  }
});

如果我将 if 语句和我 child 的渲染中的内容换成 this.props,上面的方法就可以工作了。* 但是,这意味着我以后不能通过状态更改内容,对吗?

TLDR:我想在子组件(AJAX 调用的结果)中通过 Prop 设置默认帖子,并且我希望能够通过添加 onClick 事件(另一个组件)来更改正在查看的帖子) 将更新状态。

这是解决问题的正确方法吗?

我的应用组件的当前层次结构是:

React Blog
 - Post List
  - Post Snippet (click will callback on React Blog and update Post Viewer)
 - Post Viewer (default post passed in via props)

谢谢!

编辑:

所以我最后做的是使用基于 this.state 的值在 ReactBlog 中附加 Prop 。这确保了它在我更改状态时更新并在子组件中正确呈现。但是,为此我必须将 onClick 回调链接到所有不同的子组件。这个对吗?看起来它会变得非常困惑。这是我的完整示例代码:

var ReactBlog = React.createClass({
  getInitialState: function() {
    return {
      posts: [],
    };
  },
  componentDidMount: function() {
    $.get(this.props.url, function(data) {
      if (this.isMounted()) {
        this.setState({
          posts: data,
          post: data[0]
        });
      }
    }.bind(this));
  },
  focusPost: function(slug) {
    $.get('/api/posts/' + slug, function(data) {
      this.setState({
        post: data
      })
    }.bind(this));
  },
  render: function() {
    return (
      <div className="layout">
        <div className="layout layout-sidebar">
          <PostList handleTitleClick={this.focusPost} posts={this.state.posts}/>
        </div>
        <div className="layout layout-content">
          <PostViewer post={this.state.post}/>
        </div>
      </div>
    )
  }
});

var PostList = React.createClass({
  handleTitleClick: function(slug) {
    this.props.handleTitleClick(slug);
  },
  render: function() {
    var posts = this.props.posts;

    var postSnippets = posts.map(function(post, i) {
      return <PostSnippet data={post} key={i} handleTitleClick={this.handleTitleClick}/>;
    }, this);

    return (
      <div className="posts-list">
        <ul>
          {postSnippets}
        </ul>
      </div>
    )
  }
});

var PostSnippet = React.createClass({
  handleTitleClick: function(slug) {
    this.props.handleTitleClick(slug);
  },
  render: function() {
    var post = this.props.data;
    return (
      <li>
        <h1 onClick={this.handleTitleClick.bind(this, post.slug)}>{post.title}</h1>
      </li>
    )
  }
});

var PostViewer = React.createClass({
  getInitialState: function() {
    return {
      post: this.props.post
    }
  },
  render: function() {
    /* handle check for initial load which doesn't include prop data yet */
    if (this.props.post) {
      return (
        <div>
          {this.props.post.title}
        </div>
      )
    }
    return (
      <div/>
    )
  }
});

仍然希望得到一些反馈/希望这有帮助!

最佳答案

这是一个老问题,但我认为仍然相关,所以我要投入我的 2 美分。

理想情况下,您希望将所有 ajax 调用分离到一个 Action 文件中,而不是直接在组件内部执行。无需使用 Redux 之类的东西来帮助您管理状态(此时,我建议使用 redux + react-redux),您可以使用称为“容器组件”的东西来完成所有繁重的状态提升你然后在执行主布局的组件中使用 Prop 。这是一个例子:

// childComponent.js
import React from 'react';
import axios from 'axios'; // ajax stuff similar to jquery but with promises

const ChildComponent = React.createClass({
  render: function() {
    <ul className="posts">
      {this.props.posts.map(function(post){
        return (
          <li>
            <h3>{post.title}</h3>
            <p>{post.content}</p>
          </li>
        )
      })}
    </ul>
  }
})

const ChildComponentContainer = React.createClass({
  getInitialState: function() {
    return {
      posts: []
    }
  },
  componentWillMount: function() {
    axios.get(this.props.url, function(resp) {
      this.setState({
        posts: resp.data
      });
    }.bind(this));
  },
  render: function() {
    return (
      <ChildComponent posts={this.state.posts} />
    )
  }
})

export default ChildComponentContainer;

关于javascript - 将 AJAX 结果作为 props 传递给子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28595437/

有关javascript - 将 AJAX 结果作为 props 传递给子组件的更多相关文章

  1. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  2. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  3. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  4. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  5. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  6. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  7. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  8. ruby-on-rails - 应用程序的名称是否可以作为变量使用? - 2

    当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve

  9. ruby-on-rails - 使用作为方法的值在 ruby​​ 中搜索哈希 - 2

    我在搜索我的值是方法的散列时遇到问题。我只是不想运行plan_type与键匹配的方法。defmethod(plan_type,plan,user){foo:plan_is_foo(plan,user),bar:plan_is_bar(plan,user),waa:plan_is_waa(plan,user),har:plan_is_har(user)}[plan_type]end目前如果我传入“bar”作为plan_type,所有方法都会运行,我怎么能只运行plan_is_bar方法呢? 最佳答案 这个变体怎么样?defmethod

  10. ruby - 如何将 Puma::Configuration 传递给 Sinatra? - 2

    这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp

随机推荐