在Redux返回结果之前,如何处理渲染方法?

时间:2018-07-04 03:45:05

标签: reactjs redux react-redux state

我正在创建一个获取一些api来填充结果的组件,在渲染之前需要对这些api结果进行一些转换。我使用了componentWillMount方法来设置redux状态。我需要处理render方法,直到将这些结果还原为道具。这需要一些时间。由于数据不可用,此时渲染方法将失败。我尝试设置default state,但似乎无法正常工作,因为redux state将通过mapStateToProps方法映射到道具。处理这种情况的正确有效的方法是什么?

预先感谢

5 个答案:

答案 0 :(得分:0)

通常,当您的数据不存在时,您将渲染不同的东西(或者根本不会渲染)。

{this.props.unreadMessages.length > 0 &&
    <h2>
      You have {this.props.unreadMessages.length} unread messages.
    </h2>
}

或:

if (this.props.unreadMessages.length > 0) {
  return <Main unreadMessages={this.props.unreadMessages} />;
} else {
  return <Loading />
}

props没有数据时,您还可以使用默认的初始状态并基于该状态进行渲染。也许像这样:

<h2>
 Hello, {this.props.username || this.state.username}.
</h2>

此外,建议的Ajax调用生命周期挂钩为componentDidMount

答案 1 :(得分:0)

如果数据尚未准备好,则可以使用条件渲染。像这样添加有关数据的其他指标

 render() { 
    if (!this.props.data) { 
       return null;
    }
    return <YourComponent />;
}

最好在componentDidMount生命周期中获取数据。

答案 2 :(得分:0)

我会使用三元表达式作为保护子句来检查render方法中的道具。像这样的东西,例如:

render(){
    return (<React.Fragment>
    { this.props.user ? <IntendedComponent ...this.props.user /> : <Loading user={defaultUser}/> }
    <React.Fragment/>);
}

如果尚未填充用户道具,则该道具应为空,并显示备用组件(如示例中的加载组件)或具有默认硬编码值的预期组件。数据放置到位后,您可以根据需要将数据传递到组件。

答案 3 :(得分:0)

首先componentWillMount不是调用api的好方法, 根据反应文档:

  

componentDidMount()在组件被调用后立即被调用   安装(插入树中)。需要DOM的初始化   节点应该去这里。如果您需要从远程端点加载数据,   这是实例化网络请求的好地方。

     

此方法是设置任何订阅的好地方。如果你这样做   那,别忘了取消订阅componentWillUnmount()。

以下是链接:https://reactjs.org/docs/react-component.html#componentdidmount

在加载数据之前,您可以执行以下操作: 使一个标志进入称为var getElem = jQuery('.my-button'); var getClasses = getElem.attr("class").split(' '); jQuery( getClasses ).each( function( index, value ){ if( value.indexOf( 'data-featherlight' ) != -1 ){ getElem.attr( 'data-featherlight', value.replace( 'data-featherlight', '' ) ); } } ); 的redux状态 加载数据后,您便可以执行操作了。

dataLoaded:false

render()

答案 4 :(得分:0)

由于您使用的是public class CrossSiteScriptingXSSRequestWrapper extends HttpServletRequestWrapper { private static Pattern[] patterns = new Pattern[]{ Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE), Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), Pattern.compile("", Pattern.CASE_INSENSITIVE), Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), Pattern.compile("", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE), Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE), Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL) }; public CrossSiteScriptingXSSRequestWrapper(HttpServletRequest servletRequest) { super(servletRequest); } @Override public String[] getParameterValues(String parameter) { String[] values = super.getParameterValues(parameter); if (values == null) { return null; } int count = values.length; String[] encodedValues = new String[count]; for (int i = 0; i < count; i++) { encodedValues[i] = stripXSSAttack(values[i]); } return encodedValues; } @Override public String getParameter(String parameter) { String value = super.getParameter(parameter); return stripXSSAttack(value); } @Override public String getHeader(String name) { String value = super.getHeader(name); return stripXSSAttack(value); } private String stripXSSAttack(String value) { if (value != null) { // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to // avoid encoded attacks. // value = ESAPI.encoder().canonicalize(value); // Avoid null characters value = value.replaceAll("\0", ""); // Remove all sections that match a pattern for (Pattern scriptPattern : patterns) { value = scriptPattern.matcher(value).replaceAll(""); } } return value; } } ,因此可以使用ES6默认参数在Redux中设置默认的Redux state。像这样:

Reducers

在React中,例如,当状态为const apiStatus = (state='fetching', action) => { // handle dispatch action } 时,您可以使用Conditional Renderingrender加载图标。然后,当状态为fetching时,取结果并finished的真实元素。

要在Redux中使用Async,请参见以下链接: Async Action