例如,如何将字符串形式的已解析的Promise对象映射到按钮上

时间:2019-05-26 05:37:31

标签: javascript reactjs promise callback components

我了解目前有很多类似的问题,但是对于我来说,这些问题都不是那么简单。

这是我到目前为止的诺言:

enter image description here

至少在第62和63行,我们可以通过控制台看到正在找到准确和正确的值。我的目标是将其作为值传递到someVar或以其他方式用更新后的值更新第70行。

按现状,我的按钮仅呈现Object [Promise],并且在兑现承诺后不会更改。

这基本上是我写过的第一个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 个答案:

答案 0 :(得分:2)

呈现组件是同步的。如果要执行异步操作,则组件中需要一个状态变量。在第一个渲染中,它将为空,您可以渲染一些占位符视图,例如加载微调器。然后,您将启动异步内容,并在完成后设置状态,使其再次呈现。

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>
  )
}