react – Primeiro valor em uma função map no javascript

Eu tenho uma função map do JavaScript onde eu retorno todas as fotos de um certo registro. Dentre essas fotos, uma delas tem que receber um texto, que no meu caso é Foto principal, que sempre será o primeiro elemento do array. A dúvida é que o texto sempre vai para todas as imagens, e não faço ideia de como colocar o texto apenas na primeira foto.

Segue abaixo o código em questão.

<ul>
  {fotoApi?.fotos?.map((foto, index) => (
    <li key={index} style={{ listStyle: "none" }}>
      <img
        style={cssListImg}
        src={fotoApi.fotos(index)}
        onClick={() => {
          setFile(fotoApi.fotos(index));
          setImg(null);
          setI(index);
          setImgSel(foto);
        }}
      />
      <br />
      {/* fotoApi.fotos(0) ? <>Foto principal</> : <>""</> */}
      {/* A linha acima é o que eu tentei, mas sem sucesso */}
    </li>
  ))}
</ul>

Como solicitado por @VirgilioNovic, meu “fotos” é criado da seguinte forma:

const (fotoApi, setFotoApi) = useState({fotos: (), caminhoimagem: ""});

reactjs – Añadir CodeBlock a CKEditor 5 usando React Js

¿Alguien ha conseguido añadir la opción de CodeBlock a CKEditor 5 en React Js?

Actualmente lo que tengo es lo siguiente.

<CKEditor
   editor={ClassicEditor}
   data={value}
   onChange={(event, editor) => {
     const data = editor.getData();
     onChange({ target: { name, value: data } });
   }}
/>

Y lo que quiero añadir es el plugin CodeBlocks

https://ckeditor.com/docs/ckeditor5/latest/features/code-blocks.html

javascript – Pattern usage for increment / decrement React (Hooks)

When asked to increment / decrement a particular value I usually create specific functions to handle this functionality. Like this:

  const increaseQuantity = index => {
    const currentItems = (...stock);

    currentItems(index).quantity += 1;
    setStock(currentItems);
  };

  const decreaseQuantity = index => {
    const currentItems = (...stock);

    if (currentItems(index).quantity > 1) {
      currentItems(index).quantity -= 1;
      setStock(currentItems);
    }
  };

I like this approach because it clearly separates each action. Also, it only takes one single argument which keeps things simple.

But I can also create a single function, that does both things (increment or decrement), but it uses an additional parameter action as well as logic to perform the update:

  const manageQuantity = (index, action) => {
    const currentItems = (...stock);

    if (action === "increase") {
      currentItems(index).quantity += 1;
      setStock(currentItems);
    }

    if (currentItems(index).quantity > 1 && action === "decrease") {
      currentItems(index).quantity -= 1;
      setStock(currentItems);
    }
  };

I feel that the second pattern (single function) is more prone to error. Mainly because the the second argument is a (string).

Which is considered best practice and also follows some established (or well known) design pattern? Also, is one pattern more performant than the other?

Full functioning example below:

const availableItems = (
  {
    name: "iPod Nano",
    capacity: "4GB",
    quantity: 3
  },
  {
    name: "iPod Classic",
    capacity: "30GB",
    quantity: 2
  },
  {
    name: "iPod Mini",
    capacity: "4GB",
    quantity: 5
  }
);

function FirstApp() {
  const (stock, setStock) = React.useState(availableItems);

  const increaseQuantity = index => {
    const currentItems = (...stock);
    currentItems(index).quantity += 1;
    setStock(currentItems);
  };

  const decreaseQuantity = index => {
    const currentItems = (...stock);

    if (currentItems(index).quantity > 1) {
      currentItems(index).quantity -= 1;
      setStock(currentItems);
    }
  };

  return (
    <div className="app">
      <h2>FirstApp</h2>
      {JSON.stringify(stock)}
      <hr />

      {stock.map((item, i) => (
        <div key={item.name}>
          {item.name} | <button onClick={() => increaseQuantity(i)}>+</button>
          <button onClick={() => decreaseQuantity(i)}>-</button>
        </div>
      ))}
    </div>
  );
}

function SecondApp () {
  const (stock, setStock) = React.useState(availableItems);

  const increaseQuantity = index => {
    const currentItems = (...stock);
    currentItems(index).quantity += 1;
    setStock(currentItems);
  };

  const decreaseQuantity = index => {
    const currentItems = (...stock);

    if (currentItems(index).quantity > 1) {
      currentItems(index).quantity -= 1;
      setStock(currentItems);
    }
  };

  const manageQuantity = (index, action) => {
    const currentItems = (...stock);
    if (action === "increase") {
      currentItems(index).quantity += 1;
      setStock(currentItems);
    }

    if (currentItems(index).quantity > 1 && action === "decrease") {
      currentItems(index).quantity -= 1;
      setStock(currentItems);
    }
  };

  return (
    <div className="app">
      <h2>SecondApp</h2>
      {JSON.stringify(stock)}
      <hr />

      {stock.map((item, i) => (
        <div key={item.name}>
          {item.name} |{" "}
          <button onClick={() => manageQuantity(i, "increase")}>+</button>
          <button onClick={() => manageQuantity(i, "decrease")}>-</button>
        </div>
      ))}
    </div>
  );
}


function App() {
  return (
    <React.Fragment>
      <FirstApp />
      <SecondApp />
    </React.Fragment>
  )
}

ReactDOM.render(<App/>, document.getElementById('root'));
.app {
  border: 2px solid grey;
  padding: 10px;
  margin: 10px;
}
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>

Expo React Native: Strava Authentication goes to website

Hopefully someone has already looked into this and can help me to incorporate Strava oauth. What should happen is that the user clicks on the connect with strava button and should be redirected to myApp after authorizing the app. However, strava says the redirectURL is invalid for the first 2 options (because it is a string that contains an expo URL even though it is a standalone managed workflow app). The third option with myApp is valid, but does not redirect the user back to the app or anything at all. The fourth option is valid, but the user is redirected to the website, which is of course not the goal.

const openStravaAuth = async () => {
  // These do not work
  // const redirect = await Linking.getInitialURL() + '/stravaAuth'
  // const redirect = Linking.makeUrl('/stravaAuth')
  // const redirect = 'myApp://myApp.com'

  // This does work, but redirects user to browser and that will create a whole new user if they are not logged in there
  const redirect = 'https://myApp.com/stravaAuth' // This one works
  
  const url = `https://www.strava.com/oauth/authorize?client_id=${STRAVA_CLIENT_ID}&response_type=code&redirect_uri=${redirect}&approval_prompt=force`

  const result = await WebBrowser.openAuthSessionAsync(url, redirect)
}

reactjs – React Router – Navigating to same route results in re-render

Hi i’m not sure whether this is a desired behaviour or a bug.

This is an empty create-react-app example with react-router-dom

Versions:

  • “react”: “^16.13.1”,
  • “react-dom”: “^16.13.1”,
  • “react-router-dom”: “^5.2.0”,
  • “react-scripts”: “3.4.1”

There are two routes under the Switch component:

  1. / – for Home component
  2. /contacts – for Contacts component
    import React from "react";
    import { Switch, Route, BrowserRouter as Router, Link } from "react-router-dom";
    
    class Home extends React.PureComponent {
      render() {
        console.log("Home rendered");
        return <h1>Homepage</h1>;
      }
    }
    
    //const HomeMemo = React.memo(Home);
    //const Home = () => <h1>Homepage</h1>;
    const Contacts = () => <h1>Contacts</h1>;
    
    const Header = () => {
      console.log("Header Render");
      return (
        <header className="App-header">
          <Link to="/">Home</Link>
          <br />
          <Link to="/contacts">Contacts</Link>
        </header>
      );
    };
    
    function App() {
      console.log("App Render");
      return (
        <div className="App">
          <Router>
            <Header />
            <Switch>
              <Route exact path="/" component={Home} />
              <Route exact path="/contacts" component={Contacts} />
            </Switch>
          </Router>
        </div>
      );
    }
    
    export default App;

Fiddle available here

Clicking on Home link multiple times results in a Home rendered message.

My assuption was that if we’re already on same route it would not attempt to re-render?

javascript – Share data between 2 React components using React Hooks

In my app I have 3 components:

  1. MovieSearchComponent to “house” the other 2 components
  2. MovieSearch to search an API and retrieve the data
  3. MovieResultList to display the data in the browser

Both components are wrapped in a parent container MovieSearchComponent.

My MovieSearchComponent looks like this:

interface Movie {
  original_title: string;
  id: string;
}

const MovieSearchComponent = () => {
  const (movieList, setMovies) = useState<Movie()>(());

  const addMovie = ((movies: Movie()) => {
    setMovies((...movies));
  });

  return (
    <React.Fragment>
      <MovieSearch addMovie={addMovie} />
      <MovieResultList movieList={movieList}/>      
    </React.Fragment>
  )
}

In here I have a empty MovieList array that uses the setMovies function to fill the MovieList array. There’s also a addMovie function that gets called from the MovieSearch component and takes a array as a parameter. Then I pass the MovieList array to the MovieResultList component.

The MovieSearch component:

const Search = styled.input`
  color: green;
`

const MovieSearch = ( {addMovie }) => {  
    const apikey = 'api_key=***************dad4';
    const baseurl = 'https://api.themoviedb.org/3/search/movie?'

    const searchTMDBapi = (e) => {
        e.persist()
        setMovieSearchResults(e);
    }

    const setMovieSearchResults = debounce((e) => {
        const query = e.target.value;
        fetch(baseurl + apikey + '&language=en-US&query=' + query + '&page=1&include_adult=false')
          .then(response => response.json())
          .then(data => addMovie(data.results))
  }, 500);

  return <Search placeholder="Search" onChange={searchTMDBapi}/>
}

In this function component I render a input field by using styled components. The input field calls the searchTMDBapi function when something is typed. In that method I call the setMovieSearchResults method which calls the api and sets the api data in the Hook by using .then(data => addMovie(data.results))

The addMovie Hook updates the movieList array in MovieSearchComponent and the <MovieResultList movieList={movieList}/> syntax passes the movieList array to the MovieResultList which renders it:

const MovieResultList = (props) => {
    return (
        <div>
            <ul>
                {props.movieList.map(movie => {
                    return (<li key={movie.id}>{movie.original_title}</li>)
                })}
            </ul>
        </div>
    )
}

My goal was to create 2 components. 1 to retrieve data from a external API and the other to display that data in a different component. I succeeded in that but I was wondering if there are some aspects on which I could improve this code and my React knowledge.

reactjs – React Ant design file upload only xls file validation

Im using my react project for ant design file upload, i have some conflict on this uploading, i try to validate only uploading .xls file , but its not working. i change the png to xls but not working correctly anyone know how to do that correctly?

stack blitz here

code here

function getBase64(img, callback) {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result));
  reader.readAsDataURL(img);
}

function beforeUpload(file) {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('You can only upload JPG/PNG file!');
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('Image must smaller than 2MB!');
  }
  return isJpgOrPng && isLt2M;
}

class Avatar extends React.Component {
  state = {
    loading: false,
  };

  handleChange = info => {
    if (info.file.status === 'uploading') {
      this.setState({ loading: true });
      return;
    }
    if (info.file.status === 'done') {
      // Get this url from response in real world.
      getBase64(info.file.originFileObj, imageUrl =>
        this.setState({
          imageUrl,
          loading: false,
        }),
      );
    }
  };

  render() {
    const uploadButton = (
      <div>
        <Icon type={this.state.loading ? 'loading' : 'plus'} />
        <div className="ant-upload-text">Upload</div>
      </div>
    );
    const { imageUrl } = this.state;
    return (
      <Upload
        name="avatar"
        listType="picture-card"
        className="avatar-uploader"
        showUploadList={false}
        action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
        beforeUpload={beforeUpload}
        onChange={this.handleChange}
      >
        {imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
      </Upload>
    );
  }
}

Thanks

react.js – Passing data as props to every single child component every time in React

This is my React component for rendering a post. I have data object as JSON which was fetched through an API in this component.
I’d like to separate as several react components instead of putting all together in one component.
So I created like this:

const PostDetail: React.FC = () => {
  const post = usePost(); // Fetched post data by using useSelector() from redux. It looks like: {author: {name: 'name', level: 1}, content: 'hello', createdAt: 1234567, upatedAt: 1234567, comments: (), ...more than 20 properties};

  return (
    <React.Fragment>
      <PostDetailTop post={post} />
      <PostDetailContent post={post} onClickEdit={onHandleEdit} onClickDelete={onHandleDelete} />
      <PostDetailBottom post={post} />
      <PostDetailComment post={post} />
    </React.Fragment>
  )
}

interface Post {
  author: Member;
  content: string;
  createdAt: number;
  updatedAt: number;
  comments: Comment();
  ...
}

const PostDetailTop: React.FC<{post: Post}> = ({post}) => {
  const { author } = post;

  return (
    <div>author: {author.name}</div>
  );
}

const PostDetailBottom: React.FC<{post: Post}> = ({post}) => {
  const { createdAt, updatedAt } = post;

  return (
    <div>createdAt: {createdAt}, updatedAt: {updatedAt}</div>
  );
}

interface PostDetailContentProps {
  post: Post;
  onClickEdit: () => void;
  onClickDelete: () => void;
}

const PostDetailTop: React.FC<PostDetailContentProps> = ({post, onClickEdit, onClickDelete}) => {
  const { content } = post;

  return (
    <div>
      <div>{content}</div>
      <button onClick={onClickEdit}>edit</button>
      <button onClick={onClickDelete}>delete</button>
    </div>
  );
}

const PostDetailComment: React.FC<{post: Post}> = ({post}) => {
  const { comments } = post;

  return (
    <div>
    {
      comments.map(comment => <div>comment.name</div>)
    }
    </div>
  );
}

I think this approach looks ugly.
Because every single component has to get the post object as props every time even though the child component doesn’t need the other properties of the post object.
But if I pass only necessary props to the component, it has to have it’s own Props interface even if I already defined Post interface.

I’d like to make this clean, simple and maintainable component.
Which one is better? Just passing a post object or passing a destructed post object?

reactjs – How to pass all props in one variable in React?

I’m trying to assign all props in one object and pass all of them in one variable.

Here is my code:

function Slider(props){
    return (
    
        <div className="hero-wrap js-fullheight" style={{height: "1041px"}}>
            <div className="container-fluid px-0">
                <div className="row d-md-flex">
                    <img className="one-third " src={undraw}></img>
                    <div className="one-forth>
                        <div className="text mt-5">
                            <span className="subheading">{props.subheading}</span>
                            <h1 className="mb-3">{props.title}</h1>
                            <p>{props.text}</p>
                            <p><a  href="#" className="btn btn-primary">{props.btnCourses}</a></p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
}

const IndexPage = () => {

    let sliderProps = {
        subheading: 'Hi',
        title: 'Hi',
        text: 'Ipsum ut nostrud excepteur qui qui quis exercitation minim Lorem',
        btnCourses: 'Hi'
    };

    return (
        <Slider props={sliderProps} />
    );
}

At here I don’t want to write them in <Slider /> and want to assign them out of the return and assign them like props={sliderProps} How can I do it?

Como usar Deep-linking no React Native?

Obrigado por contribuir com o Stack Overflow em Português!

  • Certifique-se de responder à pergunta. Entre em detalhes sobre a sua solução e compartilhe o que você descobriu.

Mas evite

  • Pedir esclarecimentos ou detalhes sobre outras respostas.
  • Fazer afirmações baseadas apenas na sua opinião; aponte referências ou experiências anteriores.

Para aprender mais, veja nossas dicas sobre como escrever boas respostas.