【问题标题】:How to delay rendering of components on fetch request in react native?如何在本机反应中延迟获取请求上的组件渲染?
【发布时间】:2018-08-02 06:29:14
【问题描述】:

在获取请求时,如何暂停渲染?因为在我的代码中,我在按钮单击时获取请求服务器,然后我正在渲染获取的响应。但是渲染发生在获取之前,所以我变得不确定当我映射到render 内的responseData 时的值。以下是我的代码

更新

screen.js

import { article } from "./data";
import PopupDialog from "react-native-popup-dialog";
import AddNewarticle from "./AddNewarticle";

class SecondScreen extends Component {
  state = { res: [] };
  constructor() {
    super();

    this.initialState = {
      modalVisible: false,
      Disable_Button: false,
      ViewArray: []
    };
    this.state = this.initialState;
    this.animatedValue = new Animated.Value(0);
    this.Array_Value_Index = 0;
  }
  Add_New_View_Function = () => {
    this.animatedValue.setValue(0);

    let New_Added_View_Value = { Array_Value_Index: this.Array_Value_Index };

    this.setState(
      {
        Disable_Button: true,
        ViewArray: [...this.state.ViewArray, New_Added_View_Value]
      },
      () => {
        Animated.timing(this.animatedValue, {
          toValue: 1,
          duration: 400,
          useNativeDriver: true
        }).start(() => {
          this.Array_Value_Index = this.Array_Value_Index + 1;

          this.setState({ Disable_Button: false });
        });
      }
    );
  };

  onPressButton() {
    onPressSubmit();
    Add_New_View_Function();
  }
  onPressSubmit() {
    fetch("xxxxx", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        url: this.state.url
      })
    })
      .then(response => response.json())
      .then(responseData => {
        this.setState({
          res: responseData,
          loaded: true
        });
      })
      .catch(() => {
        this.setState({ showLoading: true });
      });
  }

  render() {
    const AnimationValue = this.animatedValue.interpolate({
      inputRange: [0, 1],

      outputRange: [-59, 0]
    });
    let Render_Animated_View = this.state.ViewArray.map((item, key) => {
      if (key == this.Array_Value_Index) {
        return (
          <Animated.View
            key={key}
            style={[
              styles.Animated_View_Style,
              {
                opacity: this.animatedValue,
                transform: [{ translateY: AnimationValue }]
              }
            ]}
          >
            <Text />
          </Animated.View>
        );
      } else {
        return (
          <View key={key} style={styles.Animated_View_Style}>
            {this.state.res.map(a => (
              <TouchableOpacity onPress={() => console.log("clicked")}>
                <CardSection>
                  <View style={{ flexDirection: "row" }}>
                    <Text style={styles.textStyle}>{a.title}</Text>
                  </View>
                </CardSection>
              </TouchableOpacity>
            ))}
          </View>
        );
      }
    });
    return (
      <View style={styles.MainContainer}>
        <ScrollView>
          <View style={{ flex: 1, padding: 2 }}>{Render_Animated_View}</View>
        </ScrollView>

        <TouchableOpacity
          activeOpacity={0.7}
          style={styles.TouchableOpacityStyle}
          disabled={this.state.Disable_Button}
          onPress={() => this.popupDialog.show()}
        >
          <Image
            source={{
              uri:
                "https://reactnativecode.com/wp-content/uploads/2017/11/Floating_Button.png"
            }}
            style={styles.FloatingButtonStyle}
          />
        </TouchableOpacity>
        <PopupDialog
          ref={popupDialog => {
            this.popupDialog = popupDialog;
          }}
          dialogStyle={{ backgroundColor: "#f2ddd5", height: 100 }}
          containerStyle={{ zIndex: 50, elevation: 100 }}
          overlayBackgroundColor="#000"
          dismissOnTouchOutside={true}
        >
          <View>
            <TextInput
              style={{ height: 40 }}
              placeholder="Enter the url you want to save!"
              multiline
              onChangeText={url => this.setState({ url })}
              underlayColor="#fcc9b5"
            />

            <Button title="Ok" onPress={() => this.onPressButton.bind(this)} />
          </View>
        </PopupDialog>
      </View>
    );
  }
}
export default SecondScreen;

更新

目前我正在获取article(包含文章列表的json数据)并使用获取响应呈现一些卡片,即标题显示在卡片中。在它的最后会有一个添加按钮点击它按钮将显示一个弹出窗口,其中将有粘贴文章链接的字段,通过单击 tick 图标,它将被发送到服务器,我将收到一个 json 响应 (res)。所以我希望这个res 中的数据被渲染并显示带有res 中数据的卡片列表。这怎么做?现在我已经尝试了几种方法。所以会有2个渲染我在哪里调用这个renderArticle?请帮助..希望你明白我在说什么..任何疑问请随时问..

【问题讨论】:

  • 尝试条件渲染,更改 setState 中的状态并使用 {this.state.rendered && Your HTML to render}
  • 对不起,你能给我一个示例代码吗?
  • 请与您的代码共享一个沙箱。
  • 我已经用更多信息更新了我的问题,请帮忙
  • 请您格式化您的代码。它显示语法错误

标签: javascript reactjs react-native rendering


【解决方案1】:

如果 res 是一个对象数组

// res = [{title:'article1'},{title:'article2'}] ] 

renderArticle(){
  if(this.state.res.length){
    return this.state.res.map(newarticle =>
      // Your code
    )
  }else {
    return null
  }
}

如果 res 是下面的形式

res = {
  article1Detail: {title:'article1'}, 
  article2Detail: {title:'article2'} 
}


renderArticle(){
  if(Object.values(this.state.res).length){
    return Object.values(this.state.res).map(newarticle =>
      // Your code
    )
  }else {
    return null
  }
}

【讨论】:

    【解决方案2】:
    import { article } from "./data";
    ......
    .....
    onPressSubmit() {
         this.setState({ showLoading: true});
        fetch( // api info})
        .then((response) => response.json())
        .then((responseData) => {
            this.setState({
                showLoading: false,
                res:responseData
            })
         })
        .catch(() => {
          this.setState({showLoading: false});
        })
      }
    
    render() {
      return () {
        if (this.state.showLoading) {
          // return spinner
        }
    
        return this.renderArticle();
      }
    }
    
      renderArticle(){
    
        /**
        check if state has data then 
        render content or render null 
        (can happen when api fails)
        **/
      }
    

    【讨论】:

    • 我试过了,但它们有一些语法错误。另外,当我在 catch 中设置状态时,它会替换之前保持的值,对吗?所以我没有在渲染中得到 json 数据。
    • 语法错误?我写了这段代码来解释。我不确定它是否有效。你能分享错误吗?在 catch 你不更新你的数据而只是改变加载状态,否则你的组件将继续显示微调器
    • 我已经更新了我的问题,请检查一下。我收到了map of undefined
    • 我正在尝试将新卡片列表添加到现有卡片列表。获取请求发生在我发送新文章的链接之后。所以它发生在onPressSubmit之后。我想动态呈现新组件。如何我要这样做吗?请帮助..坚持几天..请
    • 这是截图[1]:i.stack.imgur.com/2DXxE.png。当我粘贴新链接并单击 tick icon 时,我想将新卡列表添加到现有的列表中。如何做到这一点?
    【解决方案3】:

    给 res 一个类似 [] 的初始化值或判断 res 在你的渲染函数中是未定义的

    【讨论】:

      猜你喜欢
      • 2016-01-10
      • 2023-04-11
      • 2020-11-20
      • 1970-01-01
      • 2020-10-01
      • 2011-07-07
      • 2015-08-28
      • 1970-01-01
      • 2019-04-04
      相关资源
      最近更新 更多