Как мне сопоставить разрешенный объект обещания в виде строки на кнопку, например - PullRequest
1 голос
/ 26 мая 2019

Я понимаю, что существует множество похожих вопросов, но ни один из них не был достаточно простым для моего случая.

Это поведение моего обещания на данный момент:

enter image description here

по крайней мере, в строках 62 и 63 мы можем видеть через консоль, что найдены точные и правильные значения. Моя цель - либо передать это значение в someVar, либо каким-либо другим способом обновить строку 70 с обновленным значением.

В моем нынешнем виде мои кнопки просто отображают Object [Promise] и не изменяются после выполнения обещания.

Это, по сути, моя первая функция обещания, которую я когда-либо писал, и я довольно растерялся, если честно, несмотря на некоторые подробные объяснения других людей, которые, как мне кажется, выходят за рамки того, что мне нужно знать, для создания простого обещания для вызова API .

полный код:

import React from 'react';
import {Highlight} from "react-instantsearch-dom";
import Card from '@material-ui/core/Card';
import Typography from '@material-ui/core/Typography';
import Paper from '@material-ui/core/Paper';
import Link from 'next/link';
import {makeStyles} from "@material-ui/styles";
import '../static/default.css';
import algoliasearch from "algoliasearch";

const searchClient = algoliasearch(
    **************************
);

const index = searchClient.initIndex("Parks");

const useStyles = makeStyles({
    root: {
        background: 'linear-gradient(45deg, #4496DB 30%, #5df78e 90%)',
        border: 0,
        fontSize: 16,
        borderRadius: 3,
        boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
        color: 'white',
        height: 48,
        width: "100%",
        padding: '0 30px',
    },
    card: {
        minWidth: 275,
    },
    bullet: {
        display: 'inline-block',
        margin: '0 2px',
        transform: 'scale(0.8)',
    },
    title: {
        fontSize: 14,
    },
    pos: {
        marginBottom: 12,
    },
});

function indexSearch(objId){
    return new Promise((resolve, reject) => {
        index.getObject(objId, ['fullName'], (err, content) => {
            if (content != null){
                resolve(content.fullName);
            }
            else{
                reject(Error());
            }
        });
    });
}

function NewButton({redirectId}){
    const classes = useStyles();
    var someVar = indexSearch(redirectId).then(function(result){
        console.log(result);
        return result;
    }).catch(function rejected() {console.log('rejected')});
    console.log('after' + someVar);
    return(
        <Link as={`/details/${redirectId}`} href={`/details?objectId=${redirectId}`}>
            <a>
                <button type="button" className={classes.root}>
                    {`Learn more about the ${someVar}`}
                </button>
            </a>
        </Link>
    )
}

class Hit extends React.Component{

    render() {
        const props = this.props;
        return(

            <Card>
                <Paper id="paper" square>
                    <Typography id="title" color="textPrimary" variant="h6">
                        <Highlight className="ais-Highlight-header" attribute="fullName" hit={props.hit}/>
                        <Highlight className="ais-Highlight-state" attribute="states" hit={props.hit}/>
                    </Typography>
                </Paper>
                <Paper square>
                    <Typography color="textSecondary" variant="h6">
                        <Highlight attribute="description" hit={props.hit}/>
                    </Typography>
                </Paper>
                <NewButton redirectId={props.hit.objectID}/>
            </Card>
        )
    }
}

export default Hit;

1 Ответ

2 голосов
/ 26 мая 2019

Рендеринг компонента происходит синхронно.Если вы хотите сделать что-то асинхронное, вам понадобится переменная состояния в вашем компоненте.При первом рендеринге он будет пустым, и вы можете отобразить какой-нибудь вид заполнителя, например, загрузочный счетчик.Затем вы отключите асинхронную работу, а когда она завершится, вы установите состояние, заставляющее его снова рендериться.

function NewButton({redirectId}){
  const classes = useStyles();
  const [someVar, setSomeVar] = useState(null);

  useEffect(() => {
    indexSearch(redirectId).then(result => {
      setSomeVar(result);
    }) 
  }, [])

  if (!someVar) {
    return null;
  }

  return(
      <Link as={`/details/${redirectId}`} href={`/details?objectId=${redirectId}`}>
          <a>
              <button type="button" className={classes.root}>
                  {`Learn more about the ${someVar}`}
              </button>
          </a>
      </Link>
  )
}
...