使用this.setState和来自immutability-helper的更新不会重新渲染React组件

时间:2018-07-09 16:53:39

标签: javascript reactjs google-maps

我正在使用React项目中的Google Maps API进行地图的简单实现。当用户单击基于状态对象中infoWindowStatus的状态的标记时,向他们显示一个信息窗口。如果infoWindowStatus为true,则显示信息窗口。

如果我直接更改状态并使用forceUpdate,则信息窗口会正确显示。当我使用setState时,不会显示信息窗口。 (但是,当我console.log this.state.locations [myKey] .infoWindowStatus时,我可以看到infoWindowStatus确实从false变为true。)

我遇到的问题是: 使用this.setState和来自immutability-helper的更新不会重新渲染React组件。

/// <summary>
/// Summary description for DataRoutine
/// </summary>
public class DataRoutine:System.Web.UI.Page
{
public DataRoutine()
{
    //
    // TODO: Add constructor logic here
    //
}
public void CreateRecs(string strCustId)
{
    SqlConnection mDB = new SqlConnection(@"Data Source=TEAFAMILY;Initial Catalog=BolsenF1;Integrated Security=True; MultipleActiveResultSets=true;");
    SqlCommand cmd;
    SqlDataReader rdr;
    string strSql;
    string strOFlag = "F";

    // check to see if there is an active order record
    strSql = "SELECT OStatus FROM Orders WHERE OCustID = @CustId "
        + "AND OStatus =\"Ordering\" ORDER BY OOrderID DESC;";
    cmd = new SqlCommand(strSql, mDB);
    cmd.Parameters.Add("@CustId", strCustId);
    mDB.Open();
    rdr = cmd.ExecuteReader();
    Boolean booRows = rdr.HasRows;
    if (booRows)  // when booRows is true, there are order records for the user 
    {
        rdr.Read();
        if ((string)rdr["OStatus"] != "Ordering") //status of an active order is "Ordering"
        {
            strOFlag = "T"; // "T" means there is a need to create a new Orders record
        }
    }
    else { strOFlag = "T"; }
    mDB.Close();
    if (strOFlag == "T")
    {
        // insert a new order record to create a new order number in the database
        String strStatus = "Ordering";
        strSql = "INSERT INTO Orders (OCustID, OStatus) VALUES (@CustId, @Status)";
        cmd = new SqlCommand(strSql, mDB);
        cmd.Parameters.Add("@CustId", strCustId);
        cmd.Parameters.Add("@Status", strStatus);
        mDB.Open();
        cmd.ExecuteNonQuery();
        mDB.Close();

    }

    // retrieve order No - this order No is needed when the user buys an item
    strSql = "SELECT OOrderID FROM Orders WHERE OCustID = @CustId "
        + " AND OStatus =\"Ordering\" ORDER BY OOrderID DESC;";
    cmd = new SqlCommand(strSql, mDB);
    cmd.Parameters.Add("@CustId", strCustId);
    mDB.Open();
    rdr = cmd.ExecuteReader();
    rdr.Read();
    Session["sOrderNo"] = rdr["OOrderID"];  // save order no in session variable sOrderNo
    mDB.Close();
    return;
} //end of CreateRecs method

请求的整个组件是:

import update from 'immutability-helper';

state = {

  locations : [
      {
      position: {lat: 41.3029876, lng: -72.9191306},
      title: "Pepe's Pizza",
      mappy: '',
      infoWindowStatus: false,
      key : 0,
      infoWindow :
          {
            content : "Loading...",
            contentUrl : ""
          }
      }
    ]
}

// THIS DODGEY CODE WORKS
this.state.locations[myKey].infoWindowStatus = true;
this.forceUpdate()

//THIS CODE DOES NOT WORK
this.setState(
 { locations: update(this.state.locations, { [myKey] : {infoWindowStatus: 
 {$set:true}}})
      }
);

1 个答案:

答案 0 :(得分:1)

您可以跳过不变性帮助器,而是复制locations数组,创建locations[myKey]的副本,然后覆盖infoWindowStatus

const locations = [...this.state.locations];
locations[myKey] = { ...locations[myKey], infoWindowStatus: true };
this.setState({ locations });

此外,您提供给infoWindowStatus的{​​{1}}来自NeighborhoodMap,但是您将其存储在this.state.infoWindowStatus中。