Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding slides dynamically not rendered at first time #35

Closed
lsps9150414 opened this issue Feb 6, 2017 · 9 comments
Closed

Adding slides dynamically not rendered at first time #35

lsps9150414 opened this issue Feb 6, 2017 · 9 comments

Comments

@lsps9150414
Copy link

lsps9150414 commented Feb 6, 2017

2 -06-2017 23-25-47

By logging out my slides (medicationCards) I am sure that new slide is added to the children of Carousel every time I click ADD.

render() {
    const medicationCards = this.renderMedicationCards(this.props.medications);
    console.log('medicationCards = ', medicationCards);
    return (
      <Carousel
        sliderWidth={SLIDER_WIDTH}
        itemWidth={SLIDE_ITEM_WIDTH}
        slides={medicationCards}
      >
        {medicationCards}
      </Carousel>
    );
  }

However, it is not rendered for the first time.
Based on my loggings, the actual rendered slides fall 1 cycle before slides children updates, e.g. when console.log('medicationCards = ', medicationCards); prints 3 items, 2 are rendered; when it prints 4 items, 3 are rendered.

@lsps9150414 lsps9150414 changed the title Adding slides dynamically fails at first time Adding slides dynamically not rendered at first time Feb 6, 2017
@bd-arc
Copy link
Contributor

bd-arc commented Feb 6, 2017

@lsps9150414 This is odd, considering I've tried appending dynamic slides just last week, and this was working as expected. Would you mind using the provided example as a starting point? You can add just a bit of logic and check if this works.

Note that the example still uses RN version 0.38.0. We plan on updating it soon.

@lsps9150414
Copy link
Author

lsps9150414 commented Feb 7, 2017

@bd-arc I tried playing with the example but got the same result.

2 -07-2017 15-22-22

All I did with the example is replacing this.getSlides(ENTRIES1) with my custom this.renderSlides(), which takes this.state.slides and returns a simple View.

renderSlides = () => {
        console.log('[renderSlides]', this.state.slides);
        return (
          this.state.slides.map(slide => (
            <View
              style={{ backgroundColor: '#fff', width: itemWidth, height: 100 }}
              key={`carousel-entry-${slide}`}
            >
              <Text>Slide {slide}</Text>
            </View>
          ))
        );
    }
addSlide = () => {
        const newSlides = [...this.state.slides];
        newSlides.push(newSlides.length);
        this.setState({ slides: newSlides });
    }

Do you still have the code that you try appending dynamic slides?

If Carousel takes in children and store them in it's own state. I am guessing there's something wrong with it's state lifecycle management?

@bd-arc
Copy link
Contributor

bd-arc commented Feb 7, 2017

@lsps9150414 I think your guess is spot on. I'm going to run a few tests as soon as I can before getting back to you. By the way, thank you for providing thorough details ;)

@bd-arc
Copy link
Contributor

bd-arc commented Mar 23, 2017

@lsps9150414 I'm happy to let you know that this issue should be resolved with version 2.0.3 of the plugin.

@bd-arc bd-arc closed this as completed Mar 23, 2017
@rafaelcorreiapoli
Copy link

Hi! When I append a new slide, I lose the focus on the current slide and the first slide is focused.. that is not the expected behaviour since i'm implementing infinite pagination with snap-carousel
Do you know how can I fix this? my code is exactly the same as @lsps9150414 's code

@bd-arc
Copy link
Contributor

bd-arc commented Jul 3, 2017

Hi @rafaelcorreiapoli,

I guess it has to do with this line. Still, it's pretty strange since this would mean that activeItem is undefined...

If you set firstItem to, let's say 2, is the third item always the one focused when you append a new slide?

@rafaelcorreiapoli
Copy link

Yes!
I tried to use firstItem to make the slider a "controlled" component (by keeping track of currentIndex and always forcing firstItem to be the currentIndex) but it does not work :(

@bd-arc
Copy link
Contributor

bd-arc commented Jul 17, 2017

Hi @rafaelcorreiapoli,

Sorry for the delay; I've overlooked this issue since it was closed. Would you mind opening a new one with some code that can help me reproduce the matter?

I should be able to take a look at it later this week...

@b8ne
Copy link

b8ne commented Apr 2, 2018

Did you get a solution to adding slides dynamically? Im unable to do it... Getting a Warning: Cannot update during an existing state transition (such as within 'render' or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to 'componentWillMount'.

<Carousel
    style={JobStyles.carousel}
    layout={'default'}
    data={this.state.images}
    activeSlideAlignment={'start'}
    renderItem={this._renderItem}
    sliderWidth={MIXINS.widthPercentageWithPadding('100%', 40)}
    itemWidth={80}
/>
_renderItem ({item, index}) {
        if (index === 0) {
            return (
                <TouchableOpacity
                    onPress={this._takePicture}
                    style = {JobStyles.newImagePlaceholder}
                >
                    <Image source={require('../../../assets/images/image_placeholder.png')} resizeMode="contain"
                           style={JobStyles.newImagePlaceholderImage} />
                </TouchableOpacity>
            );
        } else {
            let uri = item.uri;
            return (
                <View style={FormStyles.newImagePlaceholder}>
                    <Image source={{uri: uri}} resizeMode="contain"
                           style={JobStyles.newImagePlaceholderImage} />
                    <TouchableOpacity
                        onPress={this._removePicture(index)}
                        style = {JobStyles.newImagePlaceholder}
                    >

                    </TouchableOpacity>
                </View>
            );
        }
    }
_takePicture = () => {
        let self = this;
        const options = {
            title: 'Select Avatar',
            storageOptions: {
                skipBackup: true,
                path: 'images'
            }
        };
        ImagePicker.showImagePicker(options, (response) => {
            if (response.didCancel) {
                console.log('User cancelled image picker');
            }
            else if (response.error) {
                console.log('ImagePicker Error: ', response.error);
            }
            else if (response.customButton) {
                console.log('User tapped custom button: ', response.customButton);
            }
            else {
                self.setState({ // <== UPDATING CAROUSEL DATA HERE
                    images: [...this.state.images, {
                        uri: 'data:image/jpeg;base64,' + response.data
                    }]
                })
            }
        });
    };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants