首页 \ 问答 \ 反应传递新道具(React passing new props)

反应传递新道具(React passing new props)

所以我在一个组件中更新我的状态,然后将新的props传递给子,但是孩子没有正确更新,输入的defaultValue没有改变。 起初我以为可能是因为我正在使用this.props开始使用this.states并首先在那里应用新的道具但似乎没有工作。

父组件

this.state.newDetails == null ? '' : 
    <NewDetailsView details={this.state.newDetails} /> 

子组件:

import React, { Component } from 'react';

class NewDetailsView extends Component {
  constructor(props) {
    super(props);
    this.state = {
      details: (this.props.details!= null) ? this.props.details: null
    }
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ details: nextProps });
    this.forceUpdate();
  }

  render() {
    return (
      <div>
        <input type="text" defaultValue={this.state.details.id} />
      </div>
    );
  }
}

export default NewDetailsView ;

解决方案代码

待...


So I update my state in a component and then pass the new props into the child but the child isn't updating correctly and the defaultValue of the input is not changing. At first I thought it might be because I am using this.props so begun using this.states and applying the new props there first but doesn't seem to be working.

Parent Component

this.state.newDetails == null ? '' : 
    <NewDetailsView details={this.state.newDetails} /> 

Child component:

import React, { Component } from 'react';

class NewDetailsView extends Component {
  constructor(props) {
    super(props);
    this.state = {
      details: (this.props.details!= null) ? this.props.details: null
    }
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ details: nextProps });
    this.forceUpdate();
  }

  render() {
    return (
      <div>
        <input type="text" defaultValue={this.state.details.id} />
      </div>
    );
  }
}

export default NewDetailsView ;

Solution Code:

Pending...


原文:https://stackoverflow.com/questions/46924167
更新时间:2023-02-06 17:02

最满意答案

编辑

好的,你的问题与你的LinkBut​​ton的Style属性有关,它是只读的

public CssStyleCollection Style { get; }

但是您可以使用CssClass属性

public virtual string CssClass { get; set; }

所以你可以这样做:

在控件之外定义样式标记:

<style>
 .myclassBlock{
  text-decoration:none;
  display: block

  .myclassNone{
  text-decoration:none;
  display:none; 
}

</style>

但是,如果您在Linkbutton标记中应用条件逻辑:

<asp:LinkButton ID="lnkActivate" CssClass='<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>' runat ="server" CommandArgument='<%# Eval("ID") %>'  OnClientClick ='return confirm("You want to send email to user to activate his account?");' CommandName ="activate" Text="Send Email"   ></asp:LinkButton>

在您的输出中,您将看到:

<a onclick="return confirm(&quot;You want to send email to user to activate his account?&quot;);" id="lnkActivate" class="<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>" href="javascript:__doPostBack('lnkActivate','')">Send Email</a>

因为'<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>' '<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>' ,不是scriptlet,将以纯文本格式输出。

所以你必须做这样的事情:

我已经简化了你的LinkBut​​ton:

<form>
<asp:Repeater ID="rpHostUsersList" runat="server" OnItemDataBound="rpHostUsersList_OnItemDataBound">
    <HeaderTemplate>
        <table border="1">
            <tr>
                <td><b>Activate</b></td>
            </tr>
    </HeaderTemplate>
    <ItemTemplate>

        <tr>
            <td><%#Convert.ToBoolean(Eval("Activate")) ? "Yes" : "No"%> <asp:LinkButton ID="lnkActivate" runat="server" Text="Send Email"></asp:LinkButton></td>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>
    </form>

在后面的代码中,我已经创建了一个Datatable,只是为了绑定一些假数据:

protected void Page_Load(object sender, EventArgs e)
        {
            Activate = true;
            var ds = new DataSet();
            var dt = new DataTable();
            dt.Columns.Add("Activate");

            dt.Rows.Add(new object[] { true });
            dt.Rows.Add(new object[] { false });
            dt.Rows.Add(new object[] { true });

            ds.Tables.Add(dt);

            rpHostUsersList.DataSource = ds;
            rpHostUsersList.DataBind();
        }

所以这就是你要完成任务所需要做的事情:

protected void rpHostUsersList_OnItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var currentData = ((System.Data.DataRowView)e.Item.DataItem)["Activate"];
                var b = Convert.ToBoolean(currentData);
                var btn = (LinkButton)e.Item.FindControl("lnkActivate");
                btn.CssClass = b ? "myclassBlock" : "myclassNone";
            }
        }

OUTPUT

在此处输入图像描述


EDIT

Ok, your problem is related to Style Property of your LinkButton, which is read only

public CssStyleCollection Style { get; }

But you can use the CssClass property

public virtual string CssClass { get; set; }

So you can do something like this:

Define you style tag outside your control:

<style>
 .myclassBlock{
  text-decoration:none;
  display: block

  .myclassNone{
  text-decoration:none;
  display:none; 
}

</style>

But if you apply your conditional logic inside your Linkbutton markup:

<asp:LinkButton ID="lnkActivate" CssClass='<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>' runat ="server" CommandArgument='<%# Eval("ID") %>'  OnClientClick ='return confirm("You want to send email to user to activate his account?");' CommandName ="activate" Text="Send Email"   ></asp:LinkButton>

In your output you will see this:

<a onclick="return confirm(&quot;You want to send email to user to activate his account?&quot;);" id="lnkActivate" class="<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>" href="javascript:__doPostBack('lnkActivate','')">Send Email</a>

Because '<%#Convert.ToBoolean(Eval("Activate")) ? "myclassBlock" : "myclassNone"%>', is not scriptlet, and will be output as plain text.

So you have to do something like this:

I have semplified your LinkButton:

<form>
<asp:Repeater ID="rpHostUsersList" runat="server" OnItemDataBound="rpHostUsersList_OnItemDataBound">
    <HeaderTemplate>
        <table border="1">
            <tr>
                <td><b>Activate</b></td>
            </tr>
    </HeaderTemplate>
    <ItemTemplate>

        <tr>
            <td><%#Convert.ToBoolean(Eval("Activate")) ? "Yes" : "No"%> <asp:LinkButton ID="lnkActivate" runat="server" Text="Send Email"></asp:LinkButton></td>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>
    </form>

In code behind I have create a Datatable on the fly just to have some fake data to bind:

protected void Page_Load(object sender, EventArgs e)
        {
            Activate = true;
            var ds = new DataSet();
            var dt = new DataTable();
            dt.Columns.Add("Activate");

            dt.Rows.Add(new object[] { true });
            dt.Rows.Add(new object[] { false });
            dt.Rows.Add(new object[] { true });

            ds.Tables.Add(dt);

            rpHostUsersList.DataSource = ds;
            rpHostUsersList.DataBind();
        }

So this is what you have to do to achieve your task:

protected void rpHostUsersList_OnItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var currentData = ((System.Data.DataRowView)e.Item.DataItem)["Activate"];
                var b = Convert.ToBoolean(currentData);
                var btn = (LinkButton)e.Item.FindControl("lnkActivate");
                btn.CssClass = b ? "myclassBlock" : "myclassNone";
            }
        }

OUTPUT

enter image description here

相关问答

更多
  • 实用的正则表达式(<[^>]+) style=".*?" 将在一切合理的情况下解决这个问题。 应该删除不是第一个捕获组的匹配部分,如下所示: $output = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $input); 匹配一个<后面跟着一个或多个“not > ”,直到我们来到space和style="..."部分。 /i甚至使用STYLE="..." 。 将此匹配替换为$1 ,这是捕获的组。 如果标签不包含style="..." ,它将保持标签原样。 ...
  • 正如其他人所说,你无法设置浏览器本机提供的标题弹出窗口的样式。 但是,可以使用attr引用css中的标题内容。 例如: td.chaos:hover::before { content: attr(title); position: absolute; border: 1px solid black; background: yellow; } 这不会给你原始弹出窗口免费提供的延迟外观,但根据你的确切用例,你可能会想出一些有用的东西(可能是通过使用转换?)。 此外,请注意,此样式不会消除本 ...
  • 编辑 好的,你的问题与你的LinkButton的Style属性有关,它是只读的 public CssStyleCollection Style { get; } 但是您可以使用CssClass属性 public virtual string CssClass { get; set; } 所以你可以这样做: 在控件之外定义样式标记: