Formik FieldArray - 动态生成名称

时间:2018-05-11 22:28:15

标签: reactjs formik

我正在制作"主要照顾者"信息表格,还有一个动态添加"紧急联系人"的按钮。

使用<FieldArray name="emergencyContacts" />,有一种方法可以自动将name<Field />name组件添加到父级index,以及子级&#39}。 s values,以便Formik知道在const DEFAULT_CAREGIVER = { firstName: '', lastName: '', }; function ContactInfoForm({ parentName }) { // I have to prefix the names so that Formik updates the correct values // I'd like to remove this prefix logic, and hopefully use existing properties: // "This component is rendered within a <FieldArray name="emergencyContacts" />" function prefix(name) { return parentName ? `${parentName}.${name}` : name; } return ( <React.Fragment> <Field component={TextField} id="firstName" label="First Name" name={prefix('firstName')} required /> <Field component={TextField} id="lastName" label="Last Name" name={prefix('lastName')} required /> </React.Fragment> ); } function CaregiverForm({ name }) { return ( // I'm hoping to not have to pass the prefix path along // We have lots of reusable components in this form <ContactInfoForm parentName={name} /> ); } class PrimaryCaregiverForm extends React.Component { renderEmergencyContacts = fieldArray => { const { values } = this.props; return ( <React.Fragment> {values.emergencyContacts.length > 0 && values.emergencyContacts.map((contact, index) => ( <div key={index}> <PageTitle>Emergency Contact {index + 1}</PageTitle> <CloseButton onClick={() => fieldArray.remove(index)} /> <CaregiverForm name={`${fieldArray.name}.${index}`} {...this.props} /> </div> ))} <AddEmergencyContactButton onClick={() => fieldArray.push(DEFAULT_CAREGIVER)} /> </React.Fragment> ); }; render() { const { handleSubmit } = this.props; return ( <Form onSubmit={handleSubmit}> <PageTitle>Primary Caregiver</PageTitle> <CaregiverForm {...this.props} /> <FieldArray name="emergencyContacts" render={this.renderEmergencyContacts} /> <Button type="submit">Save & Continue</Button> </Form> ); } } const caregiverValidationSchema = { firstName: Yup.string().required('First name is required.'), lastName: Yup.string().required('Last name is required.'), }; const PrimaryCaregiverPage = withFormik({ mapPropsToValues: () => ({ ...DEFAULT_CAREGIVER, emergencyContacts: [], }), validationSchema: Yup.object().shape({ ...caregiverValidationSchema, emergencyContacts: Yup.array().of( Yup.object().shape(caregiverValidationSchema), ), }), })(PrimaryCaregiverForm); 中更新它的位置?

这是我的简化代码:

bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64_t nSearchInterval, int64_t nFees, CTransaction& txNew, CKey& key)
{
    CBlockIndex* pindexPrev = pindexBest;
    CBigNum bnTargetPerCoinDay;
    bnTargetPerCoinDay.SetCompact(nBits);

    txNew.vin.clear();
    txNew.vout.clear();

    // Mark coin stake transaction
    CScript scriptEmpty;
    scriptEmpty.clear();
    txNew.vout.push_back(CTxOut(0, scriptEmpty));

    // Choose coins to use
    int64_t nBalance = GetBalance();

    if (nBalance <= nReserveBalance)
        return false;

    vector<const CWalletTx*> vwtxPrev;

    set<pair<const CWalletTx*,unsigned int> > setCoins;
    int64_t nValueIn = 0;

    // Select coins with suitable depth
    if (!SelectCoinsSimple(nBalance - nReserveBalance, txNew.nTime, nCoinbaseMaturity + 10, setCoins, nValueIn))
        return false;

    if (setCoins.empty())
        return false;

    int64_t nCredit = 0;
    CScript scriptPubKeyKernel;
    CTxDB txdb("r");
    BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
    {
        CTxIndex txindex;
        {
            LOCK2(cs_main, cs_wallet);
            if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex))
                continue;
        }

        // Read block header
        CBlock block;
        {
            LOCK2(cs_main, cs_wallet);
            if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
                continue;
        }

        static int nMaxStakeSearchInterval = 60;
        if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval)
            continue; // only count coins meeting min age requirement

        bool fKernelFound = false;
        for (unsigned int n=0; n<min(nSearchInterval,(int64_t)nMaxStakeSearchInterval) && !fKernelFound && !fShutdown && pindexPrev == pindexBest; n++)
        {
            // Search backward in time from the given txNew timestamp
            // Search nSearchInterval seconds back up to nMaxStakeSearchInterval
            uint256 hashProofOfStake = 0, targetProofOfStake = 0;
            COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second);
            if (CheckStakeKernelHash(nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, *pcoin.first, prevoutStake, txNew.nTime - n, hashProofOfStake, targetProofOfStake))
            {
                // Found a kernel
                if (fDebug && GetBoolArg("-printcoinstake"))
                    printf("CreateCoinStake : kernel found\n");
                vector<valtype> vSolutions;
                txnouttype whichType;
                CScript scriptPubKeyOut;
                scriptPubKeyKernel = pcoin.first->vout[pcoin.second].scriptPubKey;
                if (!Solver(scriptPubKeyKernel, whichType, vSolutions))
                {
                    if (fDebug && GetBoolArg("-printcoinstake"))
                        printf("CreateCoinStake : failed to parse kernel\n");
                    break;
                }
                if (fDebug && GetBoolArg("-printcoinstake"))
                    printf("CreateCoinStake : parsed kernel type=%d\n", whichType);
                if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH || whichType != TX_SCRIPTHASH)
                {
                    if (fDebug && GetBoolArg("-printcoinstake"))
                        printf("CreateCoinStake : no support for kernel type=%d\n", whichType);
                    break;  // only support pay to public key, stealth key and pay to address
                }
                if(whichType == TX_SCRIPTHASH){//pay to stealth type if exist
//                    std::set<CStealthAddress>::iterator it;
//                    for (it = stealthAddresses.begin(); it != stealthAddresses.end(); ++it){
//                    if(!keystore.GetCScript(stealthAddresses.begin()->Encoded(), key)){
//                        if (fDebug && GetBoolArg("-printcoinstake"))
//                            printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
//                        break;  // unable to find hash of the first stealth address
//                    }

//                    }
                    return true;
                } else {//no stealth address found pay to
                    if (whichType == TX_PUBKEYHASH) // pay to address type
                    {
                        // convert to pay to public key type
                        if (!keystore.GetKey(uint160(vSolutions[0]), key))
                        {
                            if (fDebug && GetBoolArg("-printcoinstake"))
                                printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
                            break;  // unable to find corresponding public key
                        }
                        scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG;
                    }
                    if (whichType == TX_PUBKEY)
                    {
                        valtype& vchPubKey = vSolutions[0];
                        if (!keystore.GetKey(Hash160(vchPubKey), key))
                        {
                            if (fDebug && GetBoolArg("-printcoinstake"))
                                printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
                            break;  // unable to find corresponding public key
                        }

                    if (key.GetPubKey() != vchPubKey)
                    {
                        if (fDebug && GetBoolArg("-printcoinstake"))
                            printf("CreateCoinStake : invalid key for kernel type=%d\n", whichType);
                            break; // keys mismatch
                        }

                        scriptPubKeyOut = scriptPubKeyKernel;
                    }
                }

                txNew.nTime -= n;
                txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
                nCredit += pcoin.first->vout[pcoin.second].nValue;
                vwtxPrev.push_back(pcoin.first);
                txNew.vout.push_back(CTxOut(0, scriptPubKeyOut));

                if (GetWeight(block.GetBlockTime(), (int64_t)txNew.nTime) < nStakeSplitAge)
                    txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake
                if (fDebug && GetBoolArg("-printcoinstake"))
                    printf("CreateCoinStake : added kernel type=%d\n", whichType);
                fKernelFound = true;
                break;
            }
        }

        if (fKernelFound || fShutdown)
            break; // if kernel is found stop searching
    }

    if (nCredit == 0 || nCredit > nBalance - nReserveBalance)
        return false;

    BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
    {
        // Attempt to add more inputs
        // Only add coins of the same key/address as kernel
        if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey))
            && pcoin.first->GetHash() != txNew.vin[0].prevout.hash)
        {
            int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)txNew.nTime);

            // Stop adding more inputs if already too many inputs
            if (txNew.vin.size() >= 100)
                break;
            // Stop adding more inputs if value is already pretty significant
            if (nCredit >= nStakeCombineThreshold)
                break;
            // Stop adding inputs if reached reserve limit
            if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance)
                break;
            // Do not add additional significant input
            if (pcoin.first->vout[pcoin.second].nValue >= nStakeCombineThreshold)
                continue;
            // Do not add input that is still too young
            if (nTimeWeight < nStakeMinAge)
                continue;

            txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
            nCredit += pcoin.first->vout[pcoin.second].nValue;
            vwtxPrev.push_back(pcoin.first);
        }
    }

    // Calculate coin age reward
    {
        uint64_t nCoinAge;
        CTxDB txdb("r");
        if (!txNew.GetCoinAge(txdb, nCoinAge))
            return error("CreateCoinStake : failed to calculate coin age");

        int64_t nReward = GetProofOfStakeReward(nCoinAge, pindexBest);
        if (nReward <= 0)
            return false;

        nCredit += nReward;
    }

    // Set output amount
    if (txNew.vout.size() == 3)
    {
        txNew.vout[1].nValue = (nCredit / 2 / CENT) * CENT;
        txNew.vout[2].nValue = nCredit - txNew.vout[1].nValue;
    }
    else
        txNew.vout[1].nValue = nCredit;

    // Sign
    int nIn = 0;
    BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev)
    {
        if (!SignSignature(*this, *pcoin, txNew, nIn++))
            return error("CreateCoinStake : failed to sign coinstake");
    }

    // Limit size
    unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
    if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
        return error("CreateCoinStake : exceeded coinstake size limit");

    // Successfully generated coinstake
    return true;
}

0 个答案:

没有答案